昨天的博客里面有提到过,当requests.get()
获取到的网页源码中没有我们需要的信息时,需要去查看Network
里面的信息
XHR的功能是传输数据
,其中有非常重要的一种数据是用json格式写成的,和html一样,这种数据能够有组织地存储大量内容。json的数据类型是“文本”,在Python语言当中,我们把它称为字符串。我们能够非常轻易地将json格式的数据转化为列表/字典
,也能将列表/字典转为json格式的数据。
打开QQ音乐网页发现它不让我们继续往下翻页,让我们下载客户端或者是一个个点击下一页
一般我们爬取网页内容的时候是根据网页链接来获取响应的内容,但这个想要查看更多歌曲的时候,不让我们继续看,所以我们就需要观察网页链接,从它的网页参数中找规律
什么是带参数请求数据?
一般网页链接由两部分组成,前半部分是网页链接,后半部分是网页链接参数(键值对的形式出现)
一般用
?
来把这两个(链接和请求参数)连接起来,有的时候也会用#
号
一般我们想要找到我们需要爬取的信息的真正的链接(昨天直接requests.get('网页链接')
)发现获取到的内容里面根本就没有我们需要的信息(比如这个案例里面歌单列表信息真的不在用requests.get()和获到的信息里面)这种时候就需要我们去看Network里面的ALL信息
一般出来的信息里面的第0个就是我们用requests.get()获取到的代码,点击查看,显然我们要的信息不在这个里面
这种时候就需要我们去看XHR
这么多XHR怎么快速知道我们要的信息在哪个XHR里?
总的步骤:
找到了我们真正需要的XHR之后,下一步就是去找对应的网页链接
从Network中查看网页链接参数:
点击加载更多评论就会有更多的XHR,我们点开多页评论对应的网页参数进行比较,可以看到他们不一样的地方
发现每点击一次加载更多,网页链接参数里面的pagenum的值就会增加,这就是他们变化的地方,找到这个就可以解决这个不用刷新网页就继续加载信息的问题(写一个循环,每次循环都去更改pagenum的值
)
发现这个网页全部链接实在是太长了,这个时候我们需要一个把Query String Parameters(网页参数)里的内容,直接复制下来,封装为一个字典,传递给params。
requests模块里的requests.get()提供了一个参数叫params,可以让我们用字典的形式,把参数传进去。
实例代码:
mport requests
# 引用requests模块
url = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp'
for x in range(5):
params = {
'ct':'24',
'qqmusic_ver': '1298',
'new_json':'1',
'remoteplace':'sizer.yqq.song_next',
'searchid':'64405487069162918',
't':'0',
'aggr':'1',
'cr':'1',
'catZhida':'1',
'lossless':'0',
'flag_qc':'0',
'p':str(x+1),
'n':'20',
'w':'周杰伦',
'g_tk':'5381',
'loginUin':'0',
'hostUin':'0',
'format':'json',
'inCharset':'utf8',
'outCharset':'utf-8',
'notice':'0',
'platform':'yqq.json',
'needNewCode':'0'
}
# 将参数封装为字典
res_music = requests.get(url,params=params)
# 调用get方法,获取源码
json_music = res_music.json()
# 使用json()方法,将response对象,转为列表/字典
list_music = json_music['data']['song']['list']
# 一层一层地取字典,获取歌单列表
for music in list_music:
# list_music是一个列表,music是它里面的元素
print(music['name'])
# 以name为键,查找歌曲名
print('所属专辑:'+music['album']['name'])
# 查找专辑名
print('播放时长:'+str(music['interval'])+'秒')
# 查找播放时长
print('播放链接:https://y.qq.com/n/yqq/song/'+music['mid']+'.html\n\n')
# 查找播放链接
运行结果:
以前有提到过当执行状态码是4xx的时候表示服务器不让爬当前链接,这个时候需要添加请求头信息,其实请求头信息就是为了告诉服务器这不是爬虫,,这是一个浏览器
每一个请求,都会有一个Requests Headers,我们把它称作请求头。它里面会有一些关于该请求的基本信息,比如:这个请求是从什么设备什么浏览器上发出?这个请求是从哪个页面跳转而来?
user-agent(中文:用户代理)会记录你电脑的信息和浏览器版本(如我的,就是windows10的64位操作系统,使用谷歌浏览器)。
origin(中文:源头)和referer(中文:引用来源)则记录了这个请求,最初的起源是来自哪个页面。它们的区别是referer会比origin携带的信息更多些。
然后我们的代码就要变成这样:(禁止爬取的时候可以添加请求头信息,别的情况下不需要)
import requests
url = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp'
headers = {
'origin':'https://y.qq.com',
# 请求来源
'referer':'https://y.qq.com/n/yqq/song/004Z8Ihr0JIu5s.html',
# 请求来源,携带的信息比“origin”更丰富
'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
# 标记了请求从什么设备,什么浏览器上发出
}
# 伪装请求头
params = {
'ct':'24',
'qqmusic_ver': '1298',
'new_json':'1',
'remoteplace':'sizer.yqq.song_next',
'searchid':'64405487069162918',
't':'0',
'aggr':'1',
'cr':'1',
'catZhida':'1',
'lossless':'0',
'flag_qc':'0',
'p':1,
'n':'20',
'w':'周杰伦',
'g_tk':'5381',
'loginUin':'0',
'hostUin':'0',
'format':'json',
'inCharset':'utf8',
'outCharset':'utf-8',
'notice':'0',
'platform':'yqq.json',
'needNewCode':'0'
}
# 将参数封装为字典
res_music = requests.get(url,headers=headers,params=params)
# 发起请求,填入请求头和参数
总结: