爬虫功能是一点一点实现的,我们想要爬取qq音乐,首先要从爬取其中一首歌来实现。

我们打开qq音乐的官网,随便找到一首歌进入播放页面,随后按F12进入检测界面。

 如果没有数据出现的话,进行刷新页面即可。随后我们在这里找到大小为一首歌的文件,这里就是这个3.1MB的文件了,点击查看它的URL,很显然,这就是正在播放的这首歌的地址了。

 

 我们可以打开这个网址检测一下是否是我们的所需要的那首歌的地址。

很明显,这就是我们所需要的地址。那么,我们怎么用爬虫来获取这个地址呢?

我们对多首不同的歌曲地址进行对比可以得出,C400到guid前这段和vkey到uin这段才是我们所需要的获取的,其他的部分都是不变的。

 那么我们继续找这个网址是怎么生成的,这个我没什么办法,只能一个个的去翻,我们找到这个文件后,可以看到它的purl就是我们所需要的。

我们来看一下这个请求需要什么参数。

 Form Data里面是不是一长串看着都头痛的参数?不急,我们分析一下哪些是需要传进去的参数来看看。

 songmid里的参数是不是有些眼熟,我们检查一下就可以发现这就是那些歌的标识,也就是我们将所需要听的歌的songmid传进这个网址,我们就可以得到我们所需要的url了。

那么我们可以来尝试一下,我们将req_2前面的参数传入。

data={"comm":{"cv":4747474,"ct":24,"format":"json","inCharset":"utf-8","outCharset":"utf-8","notice":0,"platform":"yqq.json","needNewCode":1,"uin":1248959521,"g_tk_new_20200303":1832066374,"g_tk":1832066374},"req_1":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"6846657260","songmid":["0041N9NS36K7Hi","000T550z1xUU83","003Is7hE3aTDYm","000wVxhI2nFwoq","002BngOt1PzNGZ","004XmWlq2n1SnX","002LZ8Iv2bBWfu","003tqTBf17F7ed","002s34bV1k1W7M","004Vd5CG1YlRUU","002LNOds0rYvpK"],"songtype":[0,0,0,0,0,0,0,0,0,0,0],"uin":"1248959521","loginflag":1,"platform":"20"}}}

 很好,直接就成功了,那么我们所需要的只有purl,我们用json模块来更方便的获取purl。

这样我们就获取到我们所需要的purl,最后进行一下拼接,看看能不能正常下载。

下载成功了,那么下载一首歌的思路我们已经理顺了,只需要获取歌曲songmid就能进行下载了,那么我们接下来要做的就是获取songmid。

那么songmid在哪?我打开歌曲的页面便发现了歌曲的网址后面那串就是songmid。

那么这个网址怎么来呢?那当然是在qq音乐的搜索页面获取。

让我们来看看qq音乐的搜索界面。

 

现在思路就很明显了 ,我们只需要在搜索页面,用同样的思路获取所需要的歌曲的songmid就能进行下载了。

那么我将代码简单优化如下:

import requests
import json
from bs4 import BeautifulSoup
import urllib.request

header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
}
def get_purl(mid):
    url = 'https://u.y.qq.com/cgi-bin/musicu.fcg?'
    middata = 'data={"comm":{"cv":4747474,"ct":24,"format":"json","inCharset":"utf-8","outCharset":"utf-8","notice":0,"platform":"yqq.json","needNewCode":1,"uin":1248959521,"g_tk_new_20200303":1832066374,"g_tk":1832066374},"req_1":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"6846657260","songmid":["%s"],"songtype":[0],"uin":"1248959521","loginflag":1,"platform":"20"}}}' % (
    mid)
    try:
        r = requests.get(url+middata, headers=header)
        r.encoding = 'utf-8'
        purl_json = json.loads(r.text).get('req_1').get('data').get('midurlinfo')[0].get('purl')
        return purl_json
    except:
        print('获取purl失败')

def get_mid(w):
    url = "https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.top&searchid=58540219608212637&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=10&w=%s&_=1626671326366&cv=4747474&ct=24&format=json&inCharset=utf-8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&uin=1248959763&g_tk_new_20200303=1832066374&g_tk=1832066374&hostUin=0&loginUin=0" % (urllib.request.quote(w))
    r = requests.get(url, headers=header)
    r.encoding = 'utf-8'
    mid_json = json.loads(r.text).get('data').get('song').get('list')[0].get('mid')
    return mid_json

if __name__ == '__main__':
    music_url = "https://dl.stream.qqmusic.qq.com/"
    w = input('请输入歌曲的名称:')
    mid = get_mid(w)
    purl = get_purl(mid)
    music = requests.get(music_url+purl).content
    with open(f'music/{w}.mp3', 'wb') as f:
        f.write(music)
        print(f'{w}下载完成')

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐