Python QQ音乐爬取

Python QQ音乐爬取

没错正如你所见,这是一篇关于Python爬虫的文章。希望你在看代码前,要明确以下几点。
1、这个爬虫所爬取的网站是qq音乐的PC端官网
2、爬取的音乐只是官方允许给我们听的,不涉及Vip等付费音乐
3、代码和讲解面向有一定python爬虫实战基础的小伙伴
4、此代码其实已是好久以前写好的了,不过仍然可以爬到歌曲,后续就不知道了
5、此文章和其中的代码仅用于教学和交流,不从中获利

唠叨了这么多之后就直接上代码讲解了

import requests
import json
from lxml import etree
import os
#导入要用到的包和模块

相信看这篇文章的你也是有过爬虫经验的,尽管如此,我还是要推荐使用 requests 和 lxml 中的xpath来获取网页数据,抓包的话使用谷歌浏览器。

"""这次我们从程序最开始讲起"""
if __name__=='__main__':
"""添加headers,一般其中含有User-Agent就足够,不够的话自己试着添加Cookie、Referer和其他
请按照自己电脑的User-Agent自行更改"""
    headers={
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \
    Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'
        }
"""一个死循环让你可以一直输入歌手名进行爬歌"""     
    while(True):
        singer_name=input("请输入歌手名:")
        singer_id=get_singer_id(singer_name)
        qqmusicOfsinger(singer_id)
        print('爬取成功!')

接下来就告诉你 get_singer_id() 和 qqmusicOfsinger() 是怎么写的

"""看到这个 url 是不是有点可怕,按道理应该是可以精简的,不过我懒嘻嘻
这个url的获得是需要一点抓包经验的,你可以输入一个歌手试试,然后跟踪着找到含有其名字的那些网址
(xxxxxx)的部分其实我的QQ号,因为是qq音乐嘛,实际上不登录也可以的
"""
def get_singer_id(singer_name):
    url='https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.song&searchid=62984089150681434&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=10&w={}&g_tk=522847069&loginUin=(xxxxxxxxxx)&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0'.format(singer_name)
    response=requests.get(url,headers=headers)#获取歌手的id
    data=json.loads(response.text) #转化成字典形式便于找到id
    singer_id=data['data']['zhida']['zhida_singer']['singerMID']
    return singer_id
    

后面代码有点长,看上去没有优化,其实是故意这样,可以减少代码逻辑上的错误,多调用函数其实未必是件好事,可能会让你的代码逻辑很乱

def qqmusicOfsinger(singer_id):
"""根据歌手id访问qq音乐网站"""
    start_url='https://y.qq.com/n/yqq/singer/{}.html'.format(singer_id)
    response = requests.get(start_url,headers=headers)
    html_ele=etree.HTML(response.text)#获取源代码数据
    #获取目录下的歌曲id
    song_hrefs=html_ele.xpath('//span[@class="songlist__songname_txt"]/a/@href')
    #获取歌曲名,以便于保存
    song_names=html_ele.xpath('//span[@class="songlist__songname_txt"]/a/@title')
"""上面这些其实都已经是套路来的了,记下这个xpath解析网站基本就够用了"""
    song_ids=[]
    for href in song_hrefs:
        id=href.split('/')[-1].split('.')[0]#提取歌曲id
        song_ids.append(id) 
    #构造能找到源音频的网址
    #记录歌名的编号
    index=0
"""确实说实话,抓包获取这些url真的是一个漫长的过程,别看代码好像都不长,其实背后付出的汗水和时间是真的多,向那些默默无闻的工作者敬个礼"""
    for song_id in song_ids:
        data_url='https://u.y.qq.com/cgi-bin/musicu.fcg?&data=%7B%22req%22%3A%7B%22module%22%3A%22CDN.SrfCdnDispatchServer%22%2C%22method%22%3A%22GetCdnDispatch%22%2C%22param%22%3A%7B%22guid%22%3A%227157685530%22%2C%22calltype%22%3A0%2C%22userip%22%3A%22%22%7D%7D%2C%22req_0%22%3A%7B%22module%22%3A%22vkey.GetVkeyServer%22%2C%22method%22%3A%22CgiGetVkey%22%2C%22param%22%3A%7B%22guid%22%3A%227157685530%22%2C%22songmid%22%3A%5B%22{}%22%5D%2C%22songtype%22%3A%5B0%5D%2C%22uin%22%3A%221334724312%22%2C%22loginflag%22%3A1%2C%22platform%22%3A%2220%22%7D%7D%2C%22comm%22%3A%7B%22uin%22%3A1334724312%2C%22format%22%3A%22json%22%2C%22ct%22%3A24%2C%22cv%22%3A0%7D%7D'\
                  .format(song_id)
       
        res=requests.get(data_url,headers=headers)
        data=res.json()
        #pprint(data) #这里就可以看出我打码的时候也不是一气呵成的,是不断从获得数据中探寻的
        song_url=data['req_0']['data']['midurlinfo'][0]['purl']
        #源音频的网址的拼接
        song_url='http://ws.stream.qqmusic.qq.com/'+song_url
       """终于到激动人心的歌曲下载了"""
        result=requests.get(song_url,headers=headers)
        song_name=song_names[index]
        os.makedirs('qqmusic',exist_ok=True)#我们在代码的同目录下新建一个qqmusic的文件夹用于存歌曲
        with open("qqmusic\{}.m4a".format(song_name),"wb")as f:#要点,这些歌曲音频等数据一定要用wb
            f.write(result.content)#下载内容
        print(song_name+'下载成功')
        index+=1

到这里算是大工告成了,后面你就可以把代码用pyinstaller打包成exe文件分享给自己的朋友了,当初不知道打包的好处,现在知道了,对方电脑没有python也是可以运行的,是不是很方便。
如果真想白嫖可以去访问我上传的打包好的exe资源。有问题欢迎提问。

希望你能有所收获,喜欢就点个赞,关注一下吧,后期还会更新,拜拜。

你可能感兴趣的:(Python QQ音乐爬取)