在初学爬虫的过程中,我们会发现很多网站都使用Ajax技术动态加载数据,和常规的网站不一样,数据是动态加载的,如果我们使用常规的方法爬取网页,得到的只是一堆html代码,没有任何的数据。比如微博就是如此,我们可以通过下滑来获取更多的动态。对于这样的网页该如何抓取呢?我们以微博用户动态为例,抓取某名用户的文字动态。思来想去,抓取自己的没啥意思,不如就看看最近总上热搜的叨叨魏的微博吧。
首先我们要查看并分析Ajax请求,这样我们才能对其进行模拟。
这些链接的参数有四个,前三个type、value、containerid始终如一,其中value是用户id,containerid是107603+value;而最后一个参数since_id则是采用了since_id的分页方式,其内容是下一页第一条内容的id,这里为了便于抓取,我们可以换成传统分页方式,上述链接等效于:http://m.weibo.cn/api/container/getIndex?type=uid&value=1958015870&containerid=1076031958015870&page=2
我们再来看该请求的相应内容:
点开Preview标签,其中的mblog字段下面,包含我们所需的重要信息:attitudes_count(赞数目)、comments_count(评论数目)、reposts_count(转发数目)、created_at(发布时间)、text(微博正文)等等。
到此,我们只需要设置page的范围,就可以实现微博动态的抓取了,下面是代码:
import requests
from urllib.parse import urlencode
from pyquery import PyQuery as pq
base_url = 'https://m.weibo.cn/api/container/getIndex?'
headers = {
'Host': 'm.weibo.cn',
'Referer': 'https://m.weibo.cn/u/1958015870',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest', #设置请求为Ajax
}
max_page = 10
#模拟Ajax请求
def get_page(page):
params = {
'type': 'uid',
'value': '1958015870',
'containerid': '1076031958015870',
'page': page
}
url = base_url + urlencode(params) #合成完整的URL
try:
response = requests.get(url, headers=headers)
if response.status_code == 200: #判断响应的状态码
return response.json(), page
except requests.ConnectionError as e:
print('Error', e.args)
#解析并提取信息
def parse_page(json, page: int):
if json:
items = json.get('data').get('cards')
for index, item in enumerate(items):
if page == 1 and index == 1:
continue
else:
item = item.get('mblog', {})
weibo = {}
weibo['id'] = item.get('id')
weibo['正文'] = pq(item.get('text')).text() #借助pyquery去掉正文中的HTML
weibo['点赞'] = item.get('attitudes_count')
weibo['评论'] = item.get('comments_count')
weibo['转发'] = item.get('reposts_count')
yield weibo
if __name__ == '__main__':
for page in range(1, max_page + 1):
json = get_page(page)
results = parse_page(*json)
doc=open("output.txt","a",encoding='utf8')
for result in results:
print(result,file=doc)
doc.close()
用这个程序去看看你关注的人都说过什么吧!也可以结合我们之前写过的词频统计程序,总结一下对方的遣词造句和文化造诣。
代码参考:【Python3网络爬虫开发实战】6.3-Ajax结果提取 - 崔庆才丨静觅的文章 - 知乎 https://zhuanlan.zhihu.com/p/33877731