分析爬取网易云音乐

爬取网易云音乐

本章说的是在网易云中搜索某音乐或者歌手,从而下载搜索的内容的文章
外链地址: http://music.163.com/song/media/outer/url?id={}.mp3,外链是需要记住的,找是很难找到的

例如:http://music.163.com/song/media/outer/url?id=108418.mp3背对背拥抱
可以看出来只需要获取每首歌曲的id即可获取音乐的下载地址

  1. 分析网易云音乐
    首先搜索你想要的歌曲或者歌星,这里以搜索林俊杰为例
    点击进入到单曲
    分析爬取网易云音乐_第1张图片
    右击检查,进入到Network,因为一般都是ajax请求,所以再点击XHR然后刷新页面
    分析爬取网易云音乐_第2张图片
    然后就需要开始分析下面的请求,可以发现在这个请求中返回的JSON数据正好与页面中的数据相互匹配。
    分析爬取网易云音乐_第3张图片
    然后点开一个内容具体查看内容,发现里面有很多id,那具体哪个是歌曲的id呢,其实是很好判断的,每个id前面或者后面都跟着了name,name里面的值就代表这个id是什么的id,我们需要获取歌曲所以选择name为不潮不花钱,id为108463的的JSON数据,然后与文章开头的外链url拼接之后发现正是歌曲的下载地址

    url = http://music.163.com/song/media/outer/url?id=108463.mp3
    分析爬取网易云音乐_第4张图片
    那就先获取该JSON数据的请求url,发现是一个该请求是一个post请求,既然是post请求那么一定有请求时的From Data,往下翻就会找到请求的参数,遗憾的是这个请求参数是加密了的,那么如果想破解别的歌曲或者歌手的单曲,那么久需要找到相应的From Data,然后在发送请求时更改一下From Fata数据即可
    分析爬取网易云音乐_第5张图片
    分析爬取网易云音乐_第6张图片

  2. 上代码
    写好整体的结构并导入相关的库,定义外链地址,请求头,刚刚分析的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()
  1. 注意点:
    1. 是post请求
    2. 换一个搜索内容然后分析响应内容,发现发送请求的url没有变化,变得只是From Data,更改From Data就可以获取自己下载的歌曲了,因为只要是通过搜索歌曲或者歌星得到的这些数据,结构都是一样的,所以提取id的方法也都是一样的
      分析爬取网易云音乐_第7张图片
      因为最外壳是一个字典形式,所以可以通过键取出所对应的值,然后发现歌曲的信息都在一个列表当中,所以需要去遍历整个列表
      分析爬取网易云音乐_第8张图片
      分别提取歌名,id,歌星
      分析爬取网易云音乐_第9张图片
      当得到这个结果的时候说明离成功只要一步之遥
      分析爬取网易云音乐_第10张图片
      这时我们得到了id,歌名,歌星,剩下的就是将id和外链合并成为歌曲的下载地址,然后保存时将歌名,歌星作为保存后的歌名就大功告成了
      分析爬取网易云音乐_第11张图片
      注意:
      1. 在开头已经用{}初始化了外链下载地址
      2. 保存二进制文件要加.content,且打开文件的方式为 什么什么b,如 ab,wb,rb
        分析爬取网易云音乐_第12张图片
        加一个print(‘正在下载{} {}’.format(song_name,actor))让自己知道下载到哪里了,不然下载完了都不知道
        分析爬取网易云音乐_第13张图片

完整代码

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信息获取相对应的歌曲信息,这是爬取网易云音乐的文章,下一次我会发爬取酷我音乐的文章,而且还是用户输入的哦,我第一次写文章,希望与大家共同进步,一起加油

你可能感兴趣的:(python爬虫)