一、什么是参数
1. 每个url都由两部分组成。前半部分大多形如:https://xx.xx.xxx/xxx/xxx; 后半部分,多形如:xx=xx&xx=xxx&xxxxx=xx&……两部分使用?来连接。例如:
https://www.douban.com/search?q=%E6%B5%B7%E8%BE%B9%E7%9A%84%E5%8D%A1%E5%A4%AB%E5%8D%A1
2. 这前半部分是我们所请求的地址,它告诉服务器,我想访问这里。而后半部分,就是我们的请求所附带的参数,它会告诉服务器,我们想要什么样的数据。
参数的结构,会和字典很像,有键有值,键值用=连接;每组键值之间,使用&来连接。
而我们的请求所附带的参数是“海边的卡夫卡”:q=%E6%B5%B7%E8%BE%B9%E7%9A%84%E5%8D%A1%E5%A4%AB%E5%8D%A1(那段你看不懂的代码,它是“海边的卡夫卡”使用utf-8编码的结果)。
二、爬取评论信息
1. 首先,进入网址:https://y.qq.com/n/yqq/song/004Z8Ihr0JIu5s.html。
2. 打开Network,选中All,点击刷新。
3. 第0个请求一般都会是html。我们点开第0个请求来看看(看Preview或Response都可以),看里面有没有我们想要的评论信息。显然是没有的。我们现在去看XHR。
4. 先把Network面板清空,再点击一下精彩评论的点击加载更多,看看有没有多出来的新XHR,多出来的那一个,就应该是和评论相关的啦。
5. 我们点开这个请求的Preview,能够在['comment']['commentlist']里找到评论列表。列表的每一个元素都是字典,字典里键rootcommentcontent对应的值,就是我们要找的评论。
6. 于是我们就在找到拥有评论数据的页面链接(请求的Headers栏:General中的Request URL):
7. 之前我们直接用requests.get()请求了url。如果我们想拿到更多精彩评论。就要读懂url的各个参数。修改它们,重新发起请求。
8.读懂参数,有两个重要的方法是“观察”和“比较”。“观察”指的是阅读参数的键与值,尝试理解它的含义。“比较”指的是比较两个相近的XHR——它们有哪些不同,对应的页面显示内容有什么不同。
9.我们来观察比较,依然在“七里香”的歌曲详情页,点击精彩评论的点击加载更多按钮,此时Network会多加载出更多的XHR,但是Name为fcg_global_comment_h5…才是我们关心的XHR。
分别点开它们的Query String Parametres,比较参数之间有什么不同。
只有一个参数在变化。这个参数是pagenum,第一次点击加载更多的值为1,第二第三次点击它的值就变成了2和3。
三、代码实现
1.我们写一个循环,每次循环都去更改pagenum的值,就能爬取好多精彩评论。
import requests# 引用requests模块
for i in range(5):
res_comments=requests.get('https://c.y.qq.com/base/fcgi-bin/fcg_global_comment_h5.fcg?g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=GB2312¬ice=0&platform=yqq.json&needNewCode=0&cid=205360772&reqtype=2&biztype=1&topid=102065756&cmd=6&needmusiccrit=0&pagenum='+str(i)+'&pagesize=15&lasthotcommentid=song_102065756_3202544866_44059185&domain=qq.com&ct=24&cv=10101010')# 调用get方法,下载评论列表
json_comments=res_comments.json()# 使用json()方法,将response对象,转为列表/字典
list_comments=json_comments['comment']['commentlist']# 一层一层地取字典,获取评论列表
for comment in list_comments:# list_comments是一个列表,comment是它里面的元素
print(comment['rootcommentcontent'])# 输出评论
print('-----------------------------------')# 将不同的评论分隔开来
2. 事实上,requests模块里的requests.get()提供了一个参数叫params,到网上去搜参数例表,可以让我们用字典的形式,把参数传进去。
import requests# 引用requests模块
url='https://c.y.qq.com/base/fcgi-bin/fcg_global_comment_h5.fcg'# 歌曲评论的url参数的前面部分
for i in range(5):
params={'g_tk':'5381','loginUin':'0','hostUin':'0','format':'json','inCharset':'utf8','outCharset':'GB2312','notice':'0','platform':'yqq.json','needNewCode':'0','cid':'205360772','reqtype':'2','biztype':'1','topid':'102065756','cmd':'6','needmusiccrit':'0','pagenum':str(i),'pagesize':'15','lasthotcommentid':'song_102065756_3202544866_44059185','domain':'qq.com','ct':'24','cv':'10101010'}# 将参数封装为字典
res_comments=requests.get(url,params=params)# 调用get方法,下载这个字典
json_comments=res_comments.json()
list_comments=json_comments['comment']'commentlist']
for comment in list_comments:
print(comment['rootcommentcontent'])
print('-----------------------------------')
3. 看看我们搜索的首页URL:
https://y.qq.com/portal/search.html#page=1&searchid=1&remoteplace=txt.yqq.top&t=song&w=周杰伦
这个链接的前半部分是https://y.qq.com/portal/search.html,后半部分是page=1&searchid=1&remoteplace=txt.yqq.top&t=song&w=周杰伦,然而,分隔这两部分的符号不是?,而是#。其实在这里,#和?的功能是一样的,作用都是分隔。
观察一下后半部分的参数page=1&searchid=1&remoteplace=txt.yqq.top&t=song&w=周杰伦,page(中文:页面),searchid(中文:搜索id),remoteplace(中文:远程位置)
如果改变搜索页面(https://y.qq.com/portal/search.html#page=1&searchid=1&remoteplace=txt.yqq.top&t=song&w=周杰伦)的page这个参数我们是否可以访问到其他页面的数据呢?
还记得更快查找XHR的作吗?1️⃣先把Network面板清空,2️⃣再修改page值按回车键,3️⃣查看Network多出来的新XHR,也就是这个client_search_cp..。
4. Request Header 的用法:
每一个请求,都会有一个Requests Headers,我们把它称作请求头。它里面会有一些关于该请求的基本信息,比如:这个请求是从什么设备什么浏览器上发出?这个请求是从哪个页面跳转而来?
Requests模块允许我们去修改Headers的值。点击它的官方文档,搜索“user-agent”查看更多信息。
只需要封装一个字典就好了。和写params非常相像。
5. 参考代码:
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',
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)# 发起请求,填入请求头和参数