AR之道

爬虫精进(四) ------ 带参请求/伪装成真实浏览器

2019-07-23  本文已影响0人  千喜Ya

一.通过Query String Parametres查看参数

请你使用浏览器打开QQ音乐官网,搜索周杰伦。然后打开检查面板里的Network,刷新这个页面。当然,你也可以点击这个链接直达:
https://y.qq.com/portal/search.html#page=2&searchid=1&remoteplace=txt.yqq.top&t=song&w=%E5%91%A8%E6%9D%B0%E4%BC%A6

找到隐藏有歌曲列表的那个XHR,它的名字应该叫client_search……之类,点开它,选中Headers,你的页面看上去会像这样:

我们来到一个熟悉的界面,你能看到Request Url,很长的一个地址。现在,保持General打开,保持Response HeadersRequest Headers关闭。我们点开Query String Parametres
它里面的内容,正是请求所附带的参数,Query String Parametres,它的中文翻译是:查询字符串参数。

二.如何带参数请求数据

可以把Query String Parametres里的内容,直接复制下来,封装为一个字典,传递给params。只是有一点要特别注意:要给他们打引号,让它们变字符串。

import 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')
        # 查找播放链接

爬虫小技巧 : 先把Network面板清空,再点击一下评论(你要找的)翻页,看看有没有多出来的新XHR,多出来的那一个,就应该是和评论相关的啦。



import requests
# 引用requests模块
url = 'https://c.y.qq.com/base/fcgi-bin/fcg_global_comment_h5.fcg'
commentid = ''
# 设置一个初始commentid
for x 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':'8',
    'needcommentcrit':'0',
    'pagenum':str(x),
    'pagesize':'25',
    'lasthotcommentid':commentid,
    'domain':'qq.com',
    'ct':'24',
    'cv':'101010  '
    }
    # 将参数封装为字典,其中pagenum和lastcommentid是特殊的变量
    res_comment = requests.get(url,params=params)
    # 调用get方法,下载评论列表
    json_comment = res_comment.json()
    # 使用json()方法,将response对象,转为列表/字典
    list_comment = json_comment['comment']['commentlist']
    # 一层一层地取字典,获取评论列表
    for comment in list_comment:
    # list_comment是一个列表,comment是它里面的元素
        print(comment['rootcommentcontent'])
        # 输出评论
    commentid = list_comment[24]['commentid']
    # 将最后一个评论的id赋值给comment,准备开始下一次循环

三.伪装成真实浏览器

每一个请求,都会有一个Requests Headers,我们把它称作请求头。它里面会有一些关于该请求的基本信息,比如:这个请求是从什么设备什么浏览器上发出?这个请求是从哪个页面跳转而来?



如上图,user-agent会记录你电脑的信息和浏览器版本(如我的,就是windows10的64位操作系统,使用谷歌浏览器)。origin和referer则记录了这个请求,最初的起源是来自哪个页面。它们的区别是referer会比origin携带的信息更多些。
如果我们想告知服务器,我们不是爬虫是一个正常的浏览器,就要去修改user-agent。倘若不修改,那么这里的默认值就会是Python,会被浏览器认出来。
有趣的是,像百度的爬虫,它的user-agent就会是Baiduspider,谷歌的也会是Googlebot……如是种种。
而对于爬取某些特定信息,也要求你注明请求的来源,即origin或referer的内容。比如我有试过,在爬取歌曲详情页里的歌词时,就需要注明这个信息,否则会拿不到歌词。你可以在写练习的时候进行尝试。

请求歌曲评论案例 :

import requests
url = 'https://c.y.qq.com/base/fcgi-bin/fcg_global_comment_h5.fcg'
# 这是那个,请求歌曲评论的url
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 = {
'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':'8',
'needcommentcrit':'0',
'pagenum':0,
'pagesize':'25',
'lasthotcommentid':'',
'domain':'qq.com',
'ct':'24',
'cv':'101010  '
    }

res_music = requests.get(url,headers=headers,params=params)
# 发起请求

请求前五页歌曲的歌词 :

import requests
from bs4 import BeautifulSoup
import re

url = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp'
font = {}
for x in range(5):
    headers = {
        'origin': 'https://y.qq.com',
        # 请求来源,本案例中其实是不需要加这个参数的,只是为了演示
        'referer': 'https://y.qq.com/portal/search.html',
        # 请求来源,携带的信息比“origin”更丰富,本案例中其实是不需要加这个参数的,只是为了演示
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 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': 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 = requests.get(url,params=params,headers=headers)
    json_music = res.json()
    list_song = json_music['data']['song']['list']
    for oneSong in list_song:
        MusicID = oneSong['id']
        MusicName = oneSong['name']
        MusicMid = oneSong['mid']
        header = {
            'origin': 'https://y.qq.com',
            # 请求来源,本案例中其实是不需要加这个参数的,只是为了演示
            'referer': 'https://y.qq.com/n/yqq/song/'+ str(MusicMid)+'.html',
            # 请求来源,携带的信息比“origin”更丰富,本案例中其实是不需要加这个参数的,只是为了演示
            'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
            # 标记了请求从什么设备,什么浏览器上发出
        }
        param = {
            'nobase64': '1',
            'musicid': str(MusicID),
                     '-': 'jsonp1',
        'g_tk': '5381',
        'loginUin': '0',
        'hostUin': '0',
        'format': 'json',
        'inCharset': 'utf8',
        'outCharset': 'utf - 8',
        'notice': '0',
        'platform': 'yqq.json',
        'needNewCode': '0'
        }
        songurl = 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_yqq.fcg'
        songRes = requests.get(songurl,headers = header,params=param)
        songfont = songRes.json()
        fontstr = re.sub("[A-Za-z0-9\!\%\[\]\,\。#&;]", " ", songfont['lyric'])
        fontstr1 = ",".join(fontstr.split())
        font[str(MusicName)] = fontstr1

print(font)
上一篇 下一篇

猜你喜欢

热点阅读