失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > python爬虫抓取分页_Python爬虫—简书首页数据抓取

python爬虫抓取分页_Python爬虫—简书首页数据抓取

时间:2021-04-15 10:25:22

相关推荐

python爬虫抓取分页_Python爬虫—简书首页数据抓取

简书

本该昨天完成的文章,拖了一天。可能是没休息好吧,昨天的在思路以及代码处理上存在很多问题,废话不多说,我们一起来看一下简书首页数据的抓取。

抓取的信息

2.2)简书首页文章信息 /

包括:标题,作者,发表时间,阅读量,评论数,点赞数,打赏数,所投专题

字段位置

单页数据的获取

我们先简单看一下单页数据的抓取,所谓单页就是我们最少能获取到的数据,那么我们就先去看一下这些信息的的加载方式

检查工具

通过工具我们可以看到有一个请求连接,接着我们去看一下数据

信息详情

这些信息跟我们要抓取的没任何关系,那我们就可以直接从源码中找这些信息了

数据

通过分析我们看到每一个li标签包含我们要抓取的所有信息的信息,那就可以以这个为循环点,解析第一个页面(xpath,或者通过Beautifulsoup),这里我选择的是xpath,我遇到了一个问题,就是评论数和阅读量通过xpath抓不到(可能是路径问题),我是通过正则去获取了这两个信息,下面给部分单页信息获取源码

def getData(self,url):

print url

html = requests.get(url,headers = self.headers,cookies = self.cookies).text

response = etree.HTML(html)

item = {}

flag = 0

read = re.findall(r'ic-list-read"> (\d+)', html)

comment = re.findall(r'ic-list-comments"> (\d+)', html)

result = response.xpath('//*[@id="list-container"]/ul/li/div')

for one in result:

item[1] = one.xpath('a/text()')[0]

item[2] = one.xpath('div[1]/div/a/text()')[0]

item[3] = one.xpath('div[1]/div/span/@data-shared-at')[0]

item[4] = read[flag]

try:

item[5] = comment[flag]

except:

item[5] = u''

item[6] = one.xpath('div[2]/span/text()')[0].strip()

try:

item[7] = one.xpath('div[2]/span[2]/text()')[0].strip()

except:

item[7] = u'0'

try:

item[8] = one.xpath('div[2]/a[1]/text()')[0]

except:

item[8] = u''

flag += 1

row = [item[i] for i in range(1, 9)]

1-8分别对应之前提到的

标题,作者,发表时间,阅读量,评论数,点赞数,打赏数,所投专题

网页加载方式及分页问题

我们在首页滑动鼠标会发现,信息越来越多,但是还有一点就是可以看到URL并没有发生变化,所以其他页面的信息就是异步加载了,那么接着就要去抓包了

加载更多

通过滑动鼠标,一段时间后我们可以看到,这个连接,但其实它已经请求了很多页面了

page=2

page=3

这个时候我们看到,其实有两个异步请求,已经悄悄在页面中填充了数据

那么我们点击又会有什么变化呢?

page=4

那么我们是不是可以通过,改变页码(page)去完成分页呢?因为首页和七日热门比较类似,按照我之前爬取七日热门的思路去抓取(spiders——简书7日热门(scrapy)),但是显然精简过得URL不能抓取首页的信息,那么没办法就只能把全部的参数都怼进去试试了,首先我们来看一下除了page这个参数之外,seen_snote_ids[]参数应该在那找

第一页

我们看到第一页并没有带参数, 我们再去看一下第二页的请求信息

第二页请求信息

有很多id,那么我们应该去哪找呢,我们先去看一下第一页的源码

第一页源码信息

看到这些数字,是不是和第二页的参数有关系呢,经过对比确实和第二页的参数id一致,有了头绪我们再去看一下第三页的(进一步确定携带的参数)

第三页参数

经过分析,我们很巧的发现第三页的参数是40个第二页是20个,第一个0个,并且,第二页的id参数,我们可以在第一页源码中拿到,那第三页的是不是也可以在第二页中看到呢?,我们去看一下第二页源码

可能存在id

因为网页就是直接加载的,我们大概确定一下第二页的位置,然后对比去对比第三页的部分参数信息

第三页部分参数

大家如果仔细去对比是可以发现,确实第三页的参数包含了第一个页面和第二个页面中的id信息。

现在差不多我们对这个网页的加载方式,以及分页方式有了进一步的理解,就是之后的每一页除了page参数改变之外,携带的seen_snote_ids[]是上(几)页的所有id参数,那么这个到底有多少页呢,我真的去不断点击加载最终,page参数停留在了15页(seen_snote_ids[]的数量看更是非常大),并且也没有出现字样,我们来看一下

第十五页

我们可以看到请求的URL的长度,参数一直在增加,所以我暂且就认为i这个是15页,下边给一下获取id以及分页URL的构造示例代码:

1.获取id

html = requests.get(url,headers = self.headers,cookies = self.cookies).text

response = etree.HTML(html)

ids = response.xpath('//*[@id="list-container"]/ul/li')

for one in ids:

one = 'seen_snote_ids[]=' + one.xpath('@data-note-id')[0]

2.构造页码

def totalPage(self):

for i in range(1,16):

data = '&'.join(self.params)

url = '/?' + data + '&page={}'.format(i)

self.getData(url)

遇到的问题+样例源码

1.遇到的问题

之前按照我简书七日热门的思路去写,最后获取到的都是重复数据,并且在添加id之后也是重复数据,罗罗攀 给我看了向右奔跑老大之前关于首页分析的文章,看了之后和我的对比,感觉差不多,但是我就是出不来数据,之后各位老哥们就说可能是参数不够吧,LEONYao老哥还说可以把参数都怼进去,满状态轰炸,向右奔跑老大之后说带个cookies可行,测试之后真的可行(一个小小的cookies困扰了很长时间,没想起来带cookies)

2.示例代码

# -*- coding:utf-8 -*-

from lxml import etree

import requests

import re

from Class.store_csv import CSV

class Spider(object):

headers = {

"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36"

}

cookies = {

'UM_distinctid': '15ac11bdff316-0ce09a4511f531-67f1a39-100200-15ac11bdff447d',

'CNZZDATA1258679142': '1034687255-1492307094-%7C1493259066',

'remember_user_token': 'W1s1MjA4MDY0XSwiJDJhJDEwJFVWVjUwbXBsS1hldkc1d0l3UG5DSmUiLCIxNDk0ODkyNTg0LjczNDM2ODgiXQ%3D%3D--f04b34c274980b45e5f7ee17c2686aeb4b567197',

'_gat': '1',

'_session_id': 'N0tvclN3V09wZ25UNFloZ0NrRTBVT3ZYQUR5VkRlV1c2Tno1bnNZc3dmQm9kQ3hmOGY4a0dFUlVLMDdPYWZJdCsydGJMaENZVU1XSHdZMHozblNhUERqaldYTHNWYXVPd2tISHVCeWJtbUFwMjJxQ3lyU2NZaTNoVUZsblV4Si94N2hRRC94MkJkUjhGNkNCYm1zVmM0R0ZqR2hFSFltZnhEcXVLbG54SlNSQU5lR0dtZ2MxOWlyYWVBMVl1a1lMVkFTYS8yQVF3bGFiR2hMblcweTU5cnR5ZTluTGlZdnFKbUdFWUYzcm9sZFZLOGduWFdnUU9yN3I0OTNZbWMxQ2UvbU5aQnByQmVoMFNjR1NmaDJJSXF6WHBYQXpPQnBVRVJnaVZVQ2xUR1p4MXNUaDhQSE80N1paLzg0amlBdjRxMU15a0JORlB1YXJ4V2g0b3hYZXpjR1NkSHVVdnA2RkgvVkJmdkJzdTg5ODhnUVRCSnN2cnlwRVJvWWc4N0lZMWhCMWNSMktMMWNERktycE0wcHFhTnYyK3ZoSWFSUFQzbkVyMDlXd2d5bz0tLThrdXQ2cFdRTTNaYXFRZm5RNWtYZUE9PQ%3D%3D--bc52e90a4f1d720f4766a5894866b3764c0482dd',

'_ga': 'GA1.2.1781682389.1492310343',

'_gid': 'GA1.2.163793537.1495583991',

'Hm_lvt_0c0e9d9b1e7d617b3e6842e85b9fb068': '1495360310,1495416048,1495516194,1495583956',

'Hm_lpvt_0c0e9d9b1e7d617b3e6842e85b9fb068': '1495583991'

}

params = []

def __init__(self):

field = ['标题', '作者', '发表时间', '阅读量', '评论数', '点赞数', '打赏数', '所投专题']

self.write = CSV('main.csv', field)

def totalPage(self):

for i in range(1,16):

data = '&'.join(self.params)

url = '/?' + data + '&page={}'.format(i)

self.getData(url)

def getData(self,url):

print url

html = requests.get(url,headers = self.headers,cookies = self.cookies).text

response = etree.HTML(html)

ids = response.xpath('//*[@id="list-container"]/ul/li')

for one in ids:

one = 'seen_snote_ids[]=' + one.xpath('@data-note-id')[0]

self.params.append(one)

item = {}

flag = 0

read = re.findall(r'ic-list-read"> (\d+)', html)

comment = re.findall(r'ic-list-comments"> (\d+)', html)

result = response.xpath('//*[@id="list-container"]/ul/li/div')

for one in result:

item[1] = one.xpath('a/text()')[0]

item[2] = one.xpath('div[1]/div/a/text()')[0]

item[3] = one.xpath('div[1]/div/span/@data-shared-at')[0]

item[4] = read[flag]

try:

item[5] = comment[flag]

except:

item[5] = u''

item[6] = one.xpath('div[2]/span/text()')[0].strip()

try:

item[7] = one.xpath('div[2]/span[2]/text()')[0].strip()

except:

item[7] = u'0'

try:

item[8] = one.xpath('div[2]/a[1]/text()')[0]

except:

item[8] = u''

flag += 1

row = [item[i] for i in range(1, 9)]

self.write.writeRow(row)

if __name__ == "__main__":

jian = Spider()

jian.totalPage()

结果截图

信息详情

总结

现在想来,在爬取网站时,我们可以携带尽可能全的参数(俗话说,礼多人不怪),避免遇到我这个错误,scrapy版本正在写,有兴趣的可以私聊参考源码。

如果觉得《python爬虫抓取分页_Python爬虫—简书首页数据抓取》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。