用python爬取qq音乐中五月天的歌曲歌词

1、任务目标
① 爬五月天正规专辑的所有歌曲的歌词
② 按照年份进行情感分析,并制作词云
2、方法
在qq音乐上用Python进行爬虫,总共499首歌曲,其中包括演唱会和电影原声带等,需要进行数据清洗。
3、情感语义分析

弯路部分:
原本是想用Beautiful Soup 来抓歌词,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据,但是后来发现此路不通。

其一,因为qq音乐里的url是固定不变的,并不是每一页是一个单独的url。点击下一页,这个url永远在那里不变,摔!!


image.png

打开之后跳转到的是歌手的首页,并不是我们要的单曲页。


2.png

因为我是完全没有学过php,后来搜索了一圈才知道,好像这个翻页是用js写的(还是什么ajax?),就是实际上看不到的……反正我是找了好久也没找到那个对应499首歌曲的对应页面的url。

其二,因为Beautiful Soup要依赖标签定位,而可以看到有的歌曲有mv注释,有的歌曲有热门注释,所以源码里标签并不是非常一致。

因为是小白,这个地方也摸索了半天,后来才发现怎么也提取不到《我不愿 让你一个人》的歌名,才知道是标签xx.[1]这种写法有问题,其他歌曲都是通过xx.[1]就可以定位,而这首歌由于没有mv,所以要提取歌名的话,对应标签是xx.[0],写半天却发现此路不通。

综上,后来分析了一下,就是由于自己对php太小白,啥也不懂,所以才浪费了这么久。还有就是,其实刚开始上手某种语言时,都会经历这种比较爬坡绕路的时期,不要怕,坚持一下,多搜索下前人经验,总会有办法的。还好我没放弃~~~

好吧,那我们开始寻找另一条路。

然后我不甘心,把所有能打开的url都打开了一遍,看看都是些什么鬼。

最后让我找到了这个网址:

https://c.y.qq.com/v8/fcg-bin/fcg_v8_singer_track_cp.fcg?g_tk=5381&jsonpCallback=MusicJsonCallbacksinger_track&loginUin=0&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq&needNewCode=0&singermid=000Sp0Bz4JXH0o&order=listen&begin=0&num=30&songstatus=1

3.png

打开是酱紫的:
image.png

小小兴奋一下,仔细看里面有专辑名、歌名、歌手名,甚至还有歌词的id。
image.png

到这里就有思路了,可以用正则表达式把歌名、专辑名、歌词链接等关键字都筛选出来就好了呀~
突然有种柳暗花明的感觉呢!

但是这仅仅是499首单曲里第一页的内容,其他页呢?
通过观察发现,在url里这里很不一样!
https://c.y.qq.com/v8/fcg-bin/fcg_v8_singer_track_cp.fcg?g_tk=5381&jsonpCallback=MusicJsonCallbacksinger_track&loginUin=0&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0&singermid=000Sp0Bz4JXH0o&order=listen&begin=0&num=30&songstatus=1

begin=0&num=30决定了每页第一首歌曲的序号及歌曲数目。
只要做个循环就可以翻页了都爬下来了嘛~

代码走起,先来看看最基本的,爬了第一页的歌曲:
import re
import pandas as pd
import requests
response = requests.get("https://c.y.qq.com/v8/fcg-bin/fcg_v8_singer_track_cp.fcg?g_tk=5381&jsonpCallback=MusicJsonCallbacksinger_track&loginUin=0&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0&singermid=000Sp0Bz4JXH0o&order=listen&begin=0&num=30&songstatus=1")
response = response.text
print(response)

image.png

songname = '"songname":"(.?)","songorig"'
res1 = re.findall(songname,response)
for i in res1:
print(i)
image.png

同理,爬了专辑名、歌词还有一个musicid后面会用到。
然后只要将每一页的歌曲都抓出来就好了,用一个循环增加页码即可。
import re
import requests
for i in range(0,481,30):
response = requests.get("https://c.y.qq.com/v8/fcg-bin/fcg_v8_singer_track_cp.fcg?g_tk=5381&jsonpCallback=MusicJsonCallbacksinger_track&loginUin=0&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0&singermid=000Sp0Bz4JXH0o&order=listen&begin="+str(i)+"&num=30&songstatus=1")
response = response.text
#print(response)
songname = '"songname":"(.
?)","songorig"'
album = '"albumname":"(.?)","alertid"'
strMedia = '"strMediaMid":"(.
?)","stream"'
musicid = '"songid":(.*?),"songmid"'
res1 = re.findall(songname,response)
res2 = re.findall(album,response)
res3 = re.findall(strMedia,response)
res4 = re.findall(musicid,response)
for i in range(0,len(res1)):
if res2 == '' or res3 == '' or res4 == '' :
continue
print (str(i),'\t',res1[i],'\t',res2[i],'\t',"//y.qq.com/n/yqq/song/"+res3[i]+".html",'\t',res4[i])

image.png

这里最开始print的for循环写的是:
for i in range(0,30)
拉到最后报错说list index out of range
但代码改成for i in range(0,len(res1))之后还是有问题,实际抓取出来只有409首歌,剩下的3页90首歌因为有的专辑名为空,会同样出现list index out of range的问题,只是不报错,而是直接跳过去继续打印下一页的内容了。
后来加上if语句,将为空的元素跳过继续执行循环就好了。

关于数组有时候很容易懵b。但还是那句话,刚开始学,在还没有那么扎实的理论功底时,这样边试错、边实战是对代码理解最深刻、学得最快的方式。然后在实操之后,可以再反过来,重新看一下基础的理论知识,巩固一下基本功,此时自己的理解力肯定跟两眼一抹黑,从头学的时候不一样了,理解会更深刻的。
接下来是导出到excel中,然后根据歌词的链接,再去抓取歌词。最后就可以对歌词进行分析了~

我是直接把print出来的内容copy到txt文档中,再copy到excel即可,怎么快怎么来。
按照专辑分类,将演唱会、日语专辑等删除,按照年份对原始先做一次清理。
最后整理完一共是124首歌。

image.png

然后找到歌词页,继续解析网页源码,结果发现源码里并没有直接给出歌词,shit!
image.png

完全陷入困境,不知从何下手。
然后搜了好多大神的方法,让我找到了一位大神的github:
(https://github.com/lhtlht/qqmusic)
潜心研究了快一天啊!
最后稍微看明白一些,原来能够有效区分不同歌曲的key有两个,一个是在url中的歌曲号musicid(之前没注意,没有爬下来,后来加上的),一个是在referer里用到的歌词号songmid(也就是我们之前抓到的strMedia)
image.png

image.png

然后对大神的代码做了调整,改了好久啊,才跑成功,更改如下:
(简书的编辑器会吞空格……看我公众号的原版吧,无奈)
#抓取歌词函数
import requests
import json
import pandas as pd
import re
def getLyric(musicid,songmid):
url = 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric.fcg?nobase64=1&musicid='+musicid+'&callback=jsonp1&g_tk=5381&jsonpCallback=jsonp1&loginUin=0&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0'
header = {
'user-agent':'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
'referer':'https://y.qq.com/n/yqq/song/{}.html'.format(songmid)
}
paramters = {
'nobase64':'1',
'callback':'jsonp1',
'g_tk':'5381',
'jsonpCallback':'jsonp1',
'loginUin':'0',
'hostUin':'0',
'format':'jsonp',
'inCharset':'utf8',
'outCharset':'utf-8',
'notice':'0',
'platform':'yqq',
'needNewCode':'0'
}
html = requests.get(url=url,params=paramters,headers=header)
res = json.loads(html.text.lstrip('jsonp1(').rstrip(')'))
#由于一部分歌曲是没有上传歌词,因此没有默认为空
lyric = json.loads(html.text.lstrip('jsonp1(').rstrip(')'))['lyric']
#对歌词内容做稍微清洗
dr1 = re.compile(r'&#\d.;',re.S)
dr2 = re.compile(r'[\d+]',re.S)
dd = dr1.sub(r'',lyric)
dd = dr2.sub(r'\n',dd).replace('\n\n','\n')
return dd

带入一首《志明与春娇》的musicid和 songmid试试看:
lyric = getLyric('4830147','001Sh6UI3dh9mE')
print (lyric)


image.png

写到这里,快哭了好吗!!!

然后把大神对于歌词格式的更改稍微改了一下,便于导出。
从excel中导入musicid 和 songmid。

#抓取歌词函数 getLyric 及从excel传参
import requests
import json
import pandas as pd
import re
import openpyxl
wb = openpyxl.load_workbook(r'D:\lyric.xlsx') #打开excel文件
#print(wb.get_sheet_names()) #获取工作簿所有工作表名
sheet = wb.get_sheet_by_name('清洗') #获取工作表
#print(sheet.title) #获取sheet页的名称
def getLyric(musicid,songmid):
url = 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric.fcg?nobase64=1&musicid='+musicid+'&callback=jsonp1&g_tk=5381&jsonpCallback=jsonp1&loginUin=0&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0'
header = {
'user-agent':'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
'referer':'https://y.qq.com/n/yqq/song/{}.html'.format(songmid)
}
paramters = {
'nobase64':'1',
'callback':'jsonp1',
'g_tk':'5381',
'jsonpCallback':'jsonp1',
'loginUin':'0',
'hostUin':'0',
'format':'jsonp',
'inCharset':'utf8',
'outCharset':'utf-8',
'notice':'0',
'platform':'yqq',
'needNewCode':'0'
}
html = requests.get(url=url,params=paramters,headers=header)
res = json.loads(html.text.lstrip('jsonp1(').rstrip(')'))
#由于一部分歌曲是没有上传歌词,因此没有默认为空
lyric = json.loads(html.text.lstrip('jsonp1(').rstrip(')'))['lyric']
#对歌词内容做稍微清洗
dr1 = re.compile(r'&#\d.;',re.S)
dr2 = re.compile(r'[\d+]',re.S)
dd = dr1.sub(r'',lyric)
dd = dr2.sub(r'\n',dd).replace('\n',',')
return dd

lyric_list = []
for i in range(2,126,1):
lyric_list = getLyric(str(sheet.cell(row=i,column=5).value),str(sheet.cell(row=i,column=4).value))
print (lyric_list,'\n')


image.png

同上,copy到txt再直接粘贴到excel就好了,至此,歌词爬虫总算搞定了~
撒花~~~


image.png

这篇是比较理论的部分,下一篇会进行歌词的分析,结合年份看看我们主唱大人这几年的心-路-历-程,毕竟小伙子也变成发福中年大叔了嘛~哈哈

谢谢大家!
然后本人再次强调,小白Python选手,记性不好,单纯为个人记录之用。
本文可分享,未经允许请勿转载!
整理后的excel文档如果有人想用来分析,请在公众号(fancyfanyc)后台回复mayday即可获得下载链接。
请大神们多多指教,轻拍,喵~
江湖之大,后会有期,咱们下篇见~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,192评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,186评论 1 303
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,844评论 0 252
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,471评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,876评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,891评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,068评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,791评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,539评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,772评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,250评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,577评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,244评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,146评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,949评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,995评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,812评论 2 276

推荐阅读更多精彩内容