Ajax数据爬取
什么是Ajax,官方的来说,它不是一们编程语言,而是利用JavaScript在保证页面不被刷新、页面链接不改变的情况下与服务器交换数据并更新部分网页的技术。
通俗的来说,这个技术其实应用非常广泛,比如说,你在用网页浏览的时候,下拉最右边的进度条(可能我用的词不规范哈)然后先出现提示内容正在加载,不到一秒钟的时间就出现了新的微博内容,但你所访问的url链接并没有改变,但页面的内容却更新了,这就是Ajax技术。
Ajax有一个特殊的请求类型,叫做 xhr。在进行Ajax分析时打开Chrome的Network,有一个图标XHR,这里就是帮你过滤后的所有Ajax请求。(以手机端微博网页为例,如图)
这里就是所有的Ajax请求,你可以接着下拉,就会发现这里的响应内容就会增多。
大家是不是对Ajax请求有了初步的了解了呢,接下来就进入主题,爬取指定人的微博内容。
首先打开手机端微博的登陆网址,登上自己的微博:
url = 'https://m.weibo.cn'
以我的微博为例:
之后就是打开你的特别关注,然后搜索你喜欢的那个人,进入她的微博主页,然后F12,到Network界面下,选择XHR,F5刷新以下就会出现Ajax响应:
然后接着下拉,找寻加载页面返回内容的Ajax请求响应,并打开对其进行分析(很容易找到的):
很容易找到在所选响应下的data->cards->mblog中找到自己想要的内容,并发现其时以json形式返回的,那么我就开始分析其请求头和所携带的参数列表,寻找其中的不同,以构造自己的Ajax请求头:
观察发现在参数列表当中,刚点进去微博主页刷新得到的参数列表中没有since_id这一项,而下拉内容再返回的响应参数列表中却出现的不同的since_id,可以发现再请求响应过程中只有since_id在改变,其它参数都没有变(since_id是用来控制页面的增加的)
在搞清楚这些后我们就可以构造自己的头部,模拟Ajax请求从而爬取内容,上代码!
用到的包:
from urllib.parse import urlencode
from pyquery import PyQuery as py
import requests
构造头部和参数列表,来获得返回内容:
def get_information(since_id = '',uid = 0,):
#X-Requested-With 用来标识Ajax请求,必须得有
#Referer 用来指明请求来源 必须有
#User-Agent 伪装浏览器,必须有
headers = {'Referer': 'https://m.weibo.cn',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'}
params = {
'uid': uid,
'luicode': 10000011,
'lfid': '231093_-_selffollowed',
'type': int(uid),
'value': 5768045317,
'containerid': '107603' + str(uid),
'since_id': since_id
}
# urlencode() 方法将参数转化为URL的GET请求参数
url = 'https://m.weibo.cn/api/container/getIndex?' + urlencode(params)
response = requests.get(url,headers = headers)
#获得返回的 json 内容,做分析
json_text = response.json()
#获得 since_id 为增加页面做准备
since_id = json_text.get('data').get('cardlistInfo').get('since_id')
return json_text,since_id
分析JSON内容:
def parse_json(json):
items = json.get('data').get('cards')
for item in items:
item = item.get('mblog')
weibo = {}
weibo['发表时间'] = item.get('created_at')
weibo['手机类型'] = item.get('source')
weibo['内容'] = py(item.get('text')).text()
weibo['图片链接'] = item.get('bmiddle_pic')
weibo['点赞数'] = item.get('attitudes_count')
weibo['评论数'] = item.get('comments_count')
yield weibo
主函数:
if __name__ == '__main__':
#uid 你所要爬取的微博的ID,在响应的参数列表中可以得到,图中可以找到
uid = 5768045317
#p 爬取的页数
p = 3
#获得返回的 JSON 内容 和 since_id
s = get_information(since_id = '',uid = uid)
#解析 JSON
parse_json(s[0])
#输出解析后的内容
for i in parse_json(s[0]):
print(i)
'''
#多页爬取
for i in range(p):
s = get_information(since_id = s[1],uid = uid)
for i in parse_json(s[0]):
print(i)
'''
最后的后台结果:
我爬取的是我女朋友的微博,所以后面的就不展示啦,大家可以自己试一试
此代码献给我下铺的兄弟,希望他再也不用熬夜刷微博😄当然这个代码还可以将所有的照片都爬取下来,这之后会实现的!