python網易雲音樂爬蟲原理(python爬取付費音樂)
在開始之前,做一點小小的說明哈:
- 我只是一個python爬蟲愛好者,如果本文有侵權,請聯絡我刪除!
- 本文需要有簡單的python爬蟲基礎,主要用到兩個爬蟲模組(都是常規的)requests模組selenium模組
- 建議使用谷歌瀏覽器,方便進行抓包和資料獲取。
私信小編01即可獲取大量Python學習資料
Part1 進行網頁分析
首先開啟網易雲的網頁版網易雲
然後搜尋歌曲,這裡我就搜尋一首錦零的“空山新雨後”
這時我們來觀察網頁的url,可以發現s=後面就是我們搜尋的關鍵字
當我們換一首歌,會發現也是這樣的,正好驗證了我們的想法
所以下一步讓我們點進去一首歌,然後進行播放,看看能否直接獲取音樂檔案的url,如果能,那麼直接對url進行requests.get訪問,我們就能拿到.mp3檔案了
點進第一首“空山新雨後”,我們可以看到有一個“生成外鏈播放器”
看到這個,我心中一陣激動,彷彿就要大功告成;於是我滿懷開心的點了一下,結果。。。
好吧,不過我們不能放棄,來我們分析一下網頁
但當我們定位到兩個最有可能出現外鏈的地方時,發現什麼都沒有
不過作為“規格嚴格,功夫到家”的傳承者,我不能放棄啊,於是我又開啟了抓包工具
按照常規套路,我們定位到XHR
點選播放後,出現了一大堆東西,我們要做的就是找到其中的content-type為audio一類的包
功夫不負有心人,在尋找了一(億)會兒後,我找到了
於是我又滿懷開心的複製了這個包對應的Request-URL
貼上後訪問這個url,結果非常滿意,這就是我一直在找的url
現在我把那個url貼出來
https://m10.music.126.net/20200715163315/a075d787d191f6729a517527d6064f59/ymusic/0552/0f0e/530f/28d03e94478dcc3e0479de4b61d224e9.mp3
Part2 編寫爬蟲程式
接下來就超級簡單了
下面的程式碼是最常規的操作,應該有爬蟲基礎的都能看懂;如果有不懂的,註釋都在上面
#匯入requests包 import requests #進行UA偽裝 headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36' } #指定url url = 'https://m10.music.126.net/20200715163315/a075d787d191f6729a517527d6064f59/ymusic/0552/0f0e/530f/28d03e94478dcc3e0479de4b61d224e9.mp3' #呼叫requests.get方法對url進行訪問,和持久化儲存資料 audio_content = requests.get(url=url,headers=headers).content #存入本地 with open('空山新雨後.mp3','wb') as f : f.write(audio_content) print("空山新雨後爬取成功!!!")
Part3 更高階的
看到這裡,你可能會想,為啥根本沒用selenium模組呢?能不能直接爬取任何一首我想要的歌,而不用每首都去費心費力的找一個url呢?當然可以噠!
其實網易雲線上播放每首歌曲時,都有一個外鏈地址,這是不會變的,跟每首歌的唯一一個id繫結在一起,每首歌audio檔案的url如下:
url = 'http://music.163.com/song/media/outer/url?id=' 歌曲的id值 '.mp3'
id值的獲取也很簡單,當我們點進每首歌時,上方會出現對應的網址,那裡有id值,如下圖:
所以只需把上面程式中的url改成新的url即可
如果還想要更好的體驗效果,實現在程式裡直接搜尋歌曲,拿到id值,就需要用到selenium模組
為什麼用selenium而不用xpath或bs4?
因為搜尋頁面的資料是動態載入出來的,如果直接對搜尋頁面的網頁進行資料解析,就拿不到任何資料;以我目前的技術,就只能想到使用萬能的selenium模組,下面大概說明一下步驟:
- 進行selenium無視覺化介面設定
from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu')
- 導包
import requests import re from selenium import webdriver from time import sleep
- 指定歌曲,得到對應搜尋頁面的url
name = input('請輸入歌名:') url_1 = 'https://music.163.com/#/search/m/?s=' name '&type=1'
- 獲取搜尋頁面的html檔案
#初始化browser物件 browser = webdriver.Chrome(executable_path='chromedriver.exe',chrome_options=chrome_options) #訪問該url browser.get(url=url_1) #由於網頁中有iframe框架,進行切換 browser.switch_to.frame('g_iframe') #等待0.5秒 sleep(0.5) #抓取到頁面資訊 page_text = browser.execute_script("return document.documentElement.outerHTML") #退出瀏覽器 browser.quit()
- 用正則模組re匹配html檔案中的id值、歌名和歌手
ex1 = '<a.*?id="([0-9]*?)"' ex2 = '' ex3 = 'class="td w1">(.*?)' id_list = re.findall(ex1,page_text,re.M)[::2] song_list = re.findall(ex2,page_text,re.M) singer_list = re.findall(ex3,page_text,re.M)
- 將id值、歌名和歌手封裝成一個個元組,寫入一個列表中,再進行列印
li = list(zip(song_list,singer_list,id_list)) for i in range(len(li)): print(str(i 1) '.' str(li[i]),end='/n')
- 對滿意的id值可得到一個url,再用上面的程式對該url進行requests.get方法訪問即可
Part4 小結
終究是我才疏學淺,這個找外鏈進行爬取的方法也存在很多不足,比如不能線上播放的歌曲是無法下載的。
不過寫這樣一個小程式練練手,對自己能力的提高確是有極大幫助的。