打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
第5关

https://y.qq.com/portal/search.html#page=1&searchid=1&remoteplace=txt.yqq.top&t=lyric&w=%E5%91%A8%E6%9D%B0%E4%BC%A6

爬取歌词这道题,有的同学找歌词的时候,会直接点进一首歌的详情页,然后打开“检查”,先在element去找,然后按照<div class='lyric_cont_box'>去定位

结果发现是爬取不到内容的

那爬不到的时候,我们就要去看看Network里面的内容

检查一下,ALL的第一个请求,是否网页的第0个请求里面是否有我们要抓取的内容?

操作如下,选择Network,选择ALL,刷新一下页面,选择第一个请求,名称是“004Fs2FP1EvZYc.html”

看看Preveiw的内容,好像没有我们想要的歌词内容也

那咋办?走!到XHR找找去

寻寻觅觅之后,发现了有这么一个请求,名称是:fcg_query_lyric_yqq.fcg......反正有个lyric(歌词的意思)

点开看看Preview的内容,果然有歌词

接下来,爬它!

既然是在XHR里面的内容,那爬取的方法就是:

用requests.get()去请求数据,请求数据后,需要用json()进行解析,解析完成后再按字典和列表的格式去提取数据

自动检测
import re,requests

lyric_url = 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_yqq.fcg'
headers = {
    'origin': 'https://y.qq.com',
    'referer': 'https://y.qq.com/n/yqq/song/004Fs2FP1EvZYc.html',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
}
params = {
'nobase64': '1',
'musicid': '244115385',
'-': 'jsonp1',
'g_tk': '',
'loginUin': '0',
'hostUin': '0',
'format': 'json',
'inCharset': 'utf8',
'outCharset': 'utf-8',
'notice': '0',
'platform': 'yqq.json',
'needNewCode': '0'
}
res_lyric = requests.get(lyric_url,headers=headers,params=params)
json_lyric = res_lyric.json()
lyric = json_lyric['lyric']

print(lyric)

打印出来的结果如下:

爬是爬下来了,这也太乱七八糟了吧。助教有一种方法,把数据处理一下

在上面代码的最末尾,加上这么一段即可:

自动检测
for i in lyric.split('&#10'):
    music_str = re.sub('[A-Za-z0-9\\!\\%\\[\\]\\,\\。\\&\\#\\;]', '', i)#用正则表达式去掉无用的符号字符
    if music_str.strip():#strip去掉空行
        print(music_str)

简单地说一下这里用到的是“正则表达式”的知识,因为课堂里没有这个知识点的讲解,所以助教这里不做拓展哈~

到这里,我们确实爬取到了歌词的内容,但是,这样却只能爬取到一首歌的歌词啊。好像不符合题目要求也,那...我们是不是找错了?

嗯,也不是错,但是不太符合题目的要求

其实,题目原本希望我们去抓取的,是下面这个页面

在歌手的搜索页里,我们可以切换到“歌词”这一块的内容

同样我们先在ALL里面查看第0个请求

然后我们发现,数据依然不在这里。在这个html里面,是没有我们需要抓取的歌词内容信息的

也就是说,我们没有办法通过element去爬取歌词

下一步应该怎么做?

....(思考一下)

或许你已经想到了,我们就得从XHR里面去找了

如果没找到,那我们刷新一下页面,再用助教之前讲过的小技巧,给请求按Size排序来快速找到我们需要的请求。果然,client_search_cp 这个请求是最大的,排在最前面

既然是在XHR里面的内容,那再回忆一下爬取的方法:

1、requests.get()去请求数据,记得带上参数Params和Headers

2、请求数据后,需要用json()进行解析

3、解析完成后再按字典和列表的格式去提取数据

自动检测
import requests
import json
# 引用requests,json模块

url = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp'
headers = {
    'referer':'https://y.qq.com/portal/search.html',
    # 请求来源
    'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
    # 标记了请求从什么设备,什么浏览器上发出
    }

for x in range(5):
    params = {
    'ct':'24',
    'qqmusic_ver': '1298',
    'new_json':'1',
    'remoteplace':'sizer.yqq.lyric_next',
    'searchid':'94267071827046963',
    'aggr':'1',
    'cr':'1',
    'catZhida':'1',
    'lossless':'0',
    'sem':'1',
    't':'7',
    'p':str(x+1),
    'n':'10',
    'w':'周杰伦',
    'g_tk':'1714057807',
    'loginUin':'0',
    'hostUin':'0',
    'format':'json',
    'inCharset':'utf8',
    'outCharset':'utf-8',
    'notice':'0',
    'platform':'yqq.json',
    'needNewCode':'0'  
    }
    res = requests.get(url, params = params)
    #下载该网页,赋值给res
    jsonres = res.json()
    #使用json来解析res.text
    list_lyric = jsonres['data']['lyric']['list']
    #一层一层地取字典,获取歌词的列表

    for lyric in list_lyric:
    #lyric是一个列表,x是它里面的元素
        print(lyric['content'])
    #以content为键,查找歌词

果然,这样我们可以实现5个页面所有歌词的爬取了!

这个过程,也就是我们经过一番研究之后发现,从最初搜索结果的页面去爬取歌词是最方便简洁的

再补充一下,爬取歌词这个练习,第一次爬取下来的歌词呈现的效果如下

爬是爬下来了,怎么又太乱七八糟了吧。助教还有一种方法,把数据处理一下

解决方法:歌词里面\n其实是\\n来的,用字符串.replace('\\n','\n')就可以换行了,这是因为爬出来的歌词里面的\\n,然后打印的时候遇到\\n,会打印成\n

参考一下代码:

自动检测
    for lyric in list_lyric:
        print(lyric['content'].replace('\\n','\n'))

隐藏的终极版本:(电脑打开下载可看)

5关_歌词单曲页爬取.py2.9KB

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Python
前端领域如何实现请求中断
scrapy遇上ajax,抓取QQ音乐周杰伦专辑与歌词(6)
我要偷偷的学Python,然后惊呆所有人(第九天)
手把手教你使用Python抓取QQ音乐数据
ajax+asp.net+mssql无刷新聊天室
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服