百度搜索打开网易云热歌榜

网址是 music.163.com/#/discover/…

点击F12,Network,左边仔细看会有个toplist?id=3778678,点一下再按Preview,向下滑动会出现我们想要看到的关于热歌榜的歌曲,ok这就是它了

说明这就是我们想要提取数据的url

import requests
url = "https://music.163.com/discover/toplist?id=3778678"
headers = {
    "user-agent": "#这里填自己的UA"
resp = requests.get(url=url,headers=headers)
print(resp.text)

 ctrl+f  搜索 孤勇者,出来了,仔细看发会发现这就是热歌榜的歌曲 

 为了方便爬取可以把数据存到本地再打开,以免服务器识别把ip给禁止了

​歌曲的信息基本都是如下,我们只要提取id歌名就行,这里我们用正则表达式解析  

例子:   </li><li><a href="/song?id=1901371647">孤勇者</a>      

修改:   </li><li><a href="/song\?id=(\d+)">(.*?)</a>   

解释:在正则表达式里面?有特殊的含义,如果想匹配?,则需要在其转义,前面加一个\,即?**

这里的id是一堆数字,所以用(\d+),歌名用(.*?)匹配

import re
data_list = re.findall('<li><a href="/song\?id=(\d+)">(.*?)</a>',resp.text)
print(data_list)
发现这是列表中包含着元组类型,对其遍历就能拿到每一首响应的id和歌名
调用接口,先测试一下发现OK,即每一个id对应相应的歌曲地址:

music.163.com/song/media/… (id=1901371647歌名:孤勇者)

​​​​ (不用管接口怎么来,直接用就行) 

要知道歌曲是二进制数据,要拿到数据,再写入文件:

for id,name in data_list:
    # 引用一个接口
    music_url = f'http://music.163.com/song/media/outer/url?id={id}.mp3'
    # 对于音乐播放地址发送请求,获取二进制数据内容
    music_content = requests.get(url=music_url,headers=headers).content

接下来是写入文件,先在这个文件夹下创建一个目录,需要引入os模块

import os
# 目录名随便起
filename = "音乐\\"
if not os.path.exists(filename):
    os.mkdir(filename)
    with open(filename + name + '.mp3',"wb") as f:
        f.write(music_content)

以防止爬取速度太快引入time模块,每隔0.5秒再提取

import time
time.sleep(0.5)

完整代码如下:

import requests
import re
import os
import time
filename = "音乐\\"
if not os.path.exists(filename):
    os.mkdir(filename)
# 如果需要爬取其他榜单的歌曲,只需要更改id的值
url = "https://music.163.com/discover/toplist?id=3778678"
headers = {
    "user-agent": "# 自己的UA"
resp = requests.get(url=url,headers=headers)
# 这是2022年1月的正则匹配式,2022年11月前端代码又更新了
#data_list = re.findall('<li><a href="/song\?id=(\d+)">(.*?)</a>',resp.text)
# 做了点新修改
data_list = re.findall('<li><a href="/song?id=(\d+)">(.*?)</a>', resp.content.decode())
for id,name in data_list:
    # 引用一个接口
    music_url = f'http://music.163.com/song/media/outer/url?id={id}.mp3'
    # 对于音乐播放地址发送请求,获取二进制数据内容
    music_content = requests.get(url=music_url,headers=headers).content
    with open(filename + name + '.mp3',"wb") as f:
        f.write(music_content)
    # 延时0.5s
    time.sleep(0.5)
    print(id,name)
print("程序结束")
如果歌曲是需要VIP才能听的,那么提取数据下来之后也是听不了的,因为它已经被网易云音乐数据加密了。好消息是前200首歌中仅仅只有几首才是VIP的。

本博客文章仅供博主学习交流,博主才疏学浅,语言表达能力有限,对知识的理解、编写代码能力都有很多不足,希望各路大神多多包涵,多加指点。

分类:
后端
标签: