分析爬取網易雲音樂

爬取網易雲音樂

本章說的是在網易雲中搜索某音樂或者歌手,從而下載搜索的內容的文章
外鏈地址: http://music.163.com/song/media/outer/url?id={}.mp3,外鏈是需要記住的,找是很難找到的

例如:http://music.163.com/song/media/outer/url?id=108418.mp3背對背擁抱
可以看出來只需要獲取每首歌曲的id即可獲取音樂的下載地址

  1. 分析網易雲音樂
    首先搜索你想要的歌曲或者歌星,這裏以搜索林俊杰爲例在這裏插入圖片描述
    點擊進入到單曲
    進入到單曲
    右擊檢查,進入到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數據即可
    請求url
    post請求

  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的方法也都是一樣的
      在這裏插入圖片描述
      因爲最外殼是一個字典形式,所以可以通過鍵取出所對應的值,然後發現歌曲的信息都在一個列表當中,所以需要去遍歷整個列表
      在這裏插入圖片描述
      分別提取歌名,id,歌星
      在這裏插入圖片描述
      當得到這個結果的時候說明離成功只要一步之遙
      信息
      這時我們得到了id,歌名,歌星,剩下的就是將id和外鏈合併成爲歌曲的下載地址,然後保存時將歌名,歌星作爲保存後的歌名就大功告成了
      在這裏插入圖片描述
      注意:
      1. 在開頭已經用{}初始化了外鏈下載地址
      2. 保存二進制文件要加.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信息獲取相對應的歌曲信息,這是爬取網易雲音樂的文章,下一次我會發爬取酷我音樂的文章,而且還是用戶輸入的哦,我第一次寫文章,希望與大家共同進步,一起加油

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章