爬取网易云音乐
本章说的是在网易云中搜索某音乐或者歌手,从而下载搜索的内容的文章
外链地址: http://music.163.com/song/media/outer/url?id={}.mp3,外链是需要记住的,找是很难找到的
例如:http://music.163.com/song/media/outer/url?id=108418.mp3背对背拥抱
可以看出来只需要获取每首歌曲的id即可获取音乐的下载地址
-
分析网易云音乐
首先搜索你想要的歌曲或者歌星,这里以搜索林俊杰为例
点击进入到单曲
右击检查,进入到Network,因为一般都是ajax请求,所以再点击XHR然后刷新页面
然后就需要开始分析下面的请求,可以发现在这个请求中返回的JSON数据正好与页面中的数据相互匹配。
然后点开一个内容具体查看内容,发现里面有很多id,那具体哪个是歌曲的id呢,其实是很好判断的,每个id前面或者后面都跟着了name,name里面的值就代表这个id是什么的id,我们需要获取歌曲所以选择name为不潮不花钱,id为108463的的JSON数据,然后与文章开头的外链url拼接之后发现正是歌曲的下载地址url = http://music.163.com/song/media/outer/url?id=108463.mp3
那就先获取该JSON数据的请求url,发现是一个该请求是一个post请求,既然是post请求那么一定有请求时的From Data,往下翻就会找到请求的参数,遗憾的是这个请求参数是加密了的,那么如果想破解别的歌曲或者歌手的单曲,那么久需要找到相应的From Data,然后在发送请求时更改一下From Fata数据即可
-
上代码
写好整体的结构并导入相关的库,定义外链地址,请求头,刚刚分析的From Data数据
import requests,os
class QQyinyue(object):
def __init__(self):
self.song_url = 'http://music.163.com/song/media/outer/url?id={}.mp3' # 这是网易云音乐的播放音乐的外链地址,可以发现整个地址只是id不同,更改id即可获取不同的音乐
self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36'}
self.data = {'params': 'f/aZ47YnN/ARSX3MAN+RuDUjUpCKw/XhmYBfhAdUrnjZ5KkI2IXx3TfrBFLdGHqAxfVnif7xSysRF74vURIyzMSrroBf+4cPh9WMqQufLApOgH/5OLh/LZWgiZVeDMn8gQuBLu5szRXLrfNDXoPVlqeCC1hb4qrb5C30p5NLzbL3BSYzPIBd8urnSZMnTR3nnTrFZ7oxGfVzLPRF53QYjeitOlJJLlVTu8joB5hnU4lnQlGK2F2VU27YzrL51dy9yAEUjO5cjFY2Ocoa9vf6+A==',
'encSecKey': '1c0be5f6e973579de32be840d84c99bf021d63fa67db0e86f01bd589fe1e11d6ec9b66b9b4fc490711a8aad8160b36bbd39d7b52fff5bb4829270d9018c1ae24dc4258175a07fab990f7e1057ad5f1c4e601926628ad88117f455ff5371475a53df6f23c1a23b98ddd3cece5f1d14360d71c19f63d98fe8ffbae1f01cdd1c720'}
def parse_url(self):
pass
def save_songs(self):
pass
def main(self):
self.parse_url()
if __name__ == '__main__':
spider = QQyinyue()
spider.main()
- 注意点:
- 是post请求
- 换一个搜索内容然后分析响应内容,发现发送请求的url没有变化,变得只是From Data,更改From Data就可以获取自己下载的歌曲了,因为只要是通过搜索歌曲或者歌星得到的这些数据,结构都是一样的,所以提取id的方法也都是一样的
因为最外壳是一个字典形式,所以可以通过键取出所对应的值,然后发现歌曲的信息都在一个列表当中,所以需要去遍历整个列表
分别提取歌名,id,歌星
当得到这个结果的时候说明离成功只要一步之遥
这时我们得到了id,歌名,歌星,剩下的就是将id和外链合并成为歌曲的下载地址,然后保存时将歌名,歌星作为保存后的歌名就大功告成了
注意:- 在开头已经用{}初始化了外链下载地址
- 保存二进制文件要加.content,且打开文件的方式为 什么什么b,如 ab,wb,rb
加一个print(‘正在下载{} {}’.format(song_name,actor))让自己知道下载到哪里了,不然下载完了都不知道
完整代码
import requests,os
class QQyinyue(object):
def __init__(self):
self.song_url = 'http://music.163.com/song/media/outer/url?id={}.mp3' # 这是网易云音乐的播放音乐的外链地址,可以发现整个地址只是id不同,更改id即可获取不同的音乐
self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36'} # headers可以不用加,但加了总没错
self.data = {'params': 'f/aZ47YnN/ARSX3MAN+RuDUjUpCKw/XhmYBfhAdUrnjZ5KkI2IXx3TfrBFLdGHqAxfVnif7xSysRF74vURIyzMSrroBf+4cPh9WMqQufLApOgH/5OLh/LZWgiZVeDMn8gQuBLu5szRXLrfNDXoPVlqeCC1hb4qrb5C30p5NLzbL3BSYzPIBd8urnSZMnTR3nnTrFZ7oxGfVzLPRF53QYjeitOlJJLlVTu8joB5hnU4lnQlGK2F2VU27YzrL51dy9yAEUjO5cjFY2Ocoa9vf6+A==',
'encSecKey': '1c0be5f6e973579de32be840d84c99bf021d63fa67db0e86f01bd589fe1e11d6ec9b66b9b4fc490711a8aad8160b36bbd39d7b52fff5bb4829270d9018c1ae24dc4258175a07fab990f7e1057ad5f1c4e601926628ad88117f455ff5371475a53df6f23c1a23b98ddd3cece5f1d14360d71c19f63d98fe8ffbae1f01cdd1c720'}
def parse_url(self):
response = requests.post('https://music.163.com/weapi/cloudsearch/get/web?csrf_token=', data=self.data, headers=self.headers).json() # .json()是将请求得到的json数据转为python中的字典数据
songs = response['result']['songs'] # 因为最外壳是一个字典形式,所以可以通过键取出所对应的值
for song in songs:
song_name = song['name']
id = song['id']
ar = song['ar'] # 发现歌手的名字在一个列表当中,所以也需求去遍历这个列表
for song_actor in ar:
actor = song_actor['name']
# print(id,song_name,actor)
self.save_songs(song_name,id,actor) # 注意这个的缩进在for循环的内部,如果在外部就是将for循环遍历的最后一个结果传给save_songs方法,在类class里面叫方法,外面叫函数
def save_songs(self,song_name,id,actor):
filename = 'F:/音乐' # 保存的路径
if not os.path.exists(filename): # 做个判断,是否存在此路径,若不存在则创建,注意这个创建的是文件夹,文件夹,文件夹,说三遍
os.makedirs(filename)
down_url = self.song_url.format(id) # 拼接完整的下载地址url
res = requests.get(down_url,headers = self.headers).content # .content是将其转为二进制数据
with open(filename+'/{} {}'.format(song_name,actor),'wb')as f: # 以wb方式打开文件,b就是binary的缩写,代表二进制
f.write(res)
print('正在下载{} {}'.format(song_name,actor)) # 让自己知道下载到哪里了
def main(self):
self.parse_url()
if __name__ == '__main__':
spider = QQyinyue()
spider.main()
整体不足有很多,最不理想的就是不能直接让用户输入歌名或者歌星直接下载歌曲,而是需要改变From Data信息获取相对应的歌曲信息,这是爬取网易云音乐的文章,下一次我会发爬取酷我音乐的文章,而且还是用户输入的哦,我第一次写文章,希望与大家共同进步,一起加油
转载:https://blog.csdn.net/weixin_46146855/article/details/105633109