1. 程式人生 > >小白都懂的Python爬蟲之網易雲音樂下載

小白都懂的Python爬蟲之網易雲音樂下載

微信又改版了,為了方便第一時間看到我們的推送,請按照下列操作,設定“置頂”:點選上方藍色字型“程式設計師之家”-點選右上角“…”-點選“設為星標”。

可以啦,讓我們繼續相互陪伴。

源 /網路

目標

偶然的一次機會聽到了房東的貓的《雲煙成雨》,瞬間迷上了這慵懶的嗓音和學生氣的歌詞,然後一直去迴圈聽她們的歌。然後還特意去刷了動漫《我是江小白》,好期待第二季…

我多想在見你,哪怕匆匆一眼就別離…
好了,不說廢話了。這次的目標主要是根據網易雲中歌手的ID,下載該歌手的熱門音樂的歌詞和音訊,並儲存到本地的資料夾中。

配置基礎

Python

Selenium(配置方法參照:Selenium配置)

Chrome瀏覽器(其它的也可以,需要進行相應的修改)

分析

如果爬取過網易雲的網站的小夥伴都應該知道網易雲是有反爬取機制的,POST時需要對一些資訊的引數進行加密函式的模擬。但是這裡為了簡便,小白也能理解。直接使用了Selenium來模擬登入,然後使用介面來直接下載音樂和歌詞。

實驗步驟:

  • 根據歌手ID獲取該歌手的熱門歌曲列表,歌曲名稱和連結,並儲存到csv檔案中;

  • 讀取csv檔案,根據歌曲連結,提取歌曲ID,然後利用相應的介面,下載音樂和歌詞;

  • 將音樂和歌詞儲存到本地。

Python實現

該部分將對幾個關鍵的函式進行介紹…

獲取歌手資訊
利用Selenium我們就不需要看對網頁的請求了,直接可以從網頁原始碼中提取相應的資訊。檢視歌手頁面原始碼可以發現,我們需要的資訊在iframe框架內,所以我們先需要切換到iframe:

browser.switch_to.frame('contentFrame')

繼續往下看,發現我們需要的歌曲名字和連結是在id=”hotsong-list”的標籤中,然後每一行對應的是一個tr標籤。所以先獲取所有的tr內容,然後遍歷單個tr。

data = browser.find_element_by_id("hotsong-list").find_elements_by_tag_name("tr")

注意:前一個是find_element,後一個是find_elements,後者返回一個列表。

接下來就是解析單個tr標籤的內容,獲取歌曲名字和連結,可以發現兩者在class=”txt”標籤中,而且連結是href屬性,名字是title屬性,可以直接通過get_attribute()函式獲取。

for i in range(len(data)):
   content = data[i].find_element_by_class_name("txt")
   href = content.find_element_by_tag_name("a").get_attribute("href")
   title = content.find_element_by_tag_name("b").get_attribute("title")
   song_info.append((title, href))

下載歌詞

網易雲有個獲取歌詞的介面,連結為:http://music.163.com/api/song…

連結中的數字就是歌曲的id,所以我們擁有歌曲id後,可以直接從該連結下載歌詞,歌詞檔案是json格式,所以我們需要用到json包。

而且直接獲取的歌詞中,每行有一個時間軸,需要用正則表示式來剔除,完整程式碼如下:

def get_lyric(self):
   url = 'http://music.163.com/api/song/lyric?' + 'id=' + str(self.song_id) + '&lv=1&kv=1&tv=-1'
   r = requests.get(url)
   json_obj = r.text
   j = json.loads(json_obj)
   lyric = j['lrc']['lyric']
   # 利用正則表示式去除時間軸
   regex = re.compile(r'\[.*\]')
   final_lyric = re.sub(regex, '', lyric)
   return final_lyric

下載音訊

網易雲也提供了音訊檔案的介面,連結為:http://music.163.com/song/med…

連結中的數字為歌曲的id,可以直接根據歌曲的id來下載音訊檔案。完整程式碼如下:

def get_mp3(self):
   url = 'http://music.163.com/song/media/outer/url?id=' + str(self.song_id)+'.mp3'
   try:
       print("正在下載:{0}".format(self.song_name))
       urllib.request.urlretrieve(url, '{0}/{1}.mp3'.format(self.path, self.song_name))
       print("Finish...")
   except:
       print("Fail...")

Reference
python 根據網易雲歌曲的ID 直接下載歌曲  https://blog.csdn.net/qq_38282706/article/details/80300546
Windows上安裝Selenium爬取網易雲歌曲  https://zhuanlan.zhihu.com/p/42078956
原始碼地址

Github:https://github.com/blueberryc/web_crawler/blob/master/code/WYmusic.zip

公眾號內回覆“1”帶你進粉絲群640?wx_fmt=gif