Python 咪咕音樂爬取

Python 咪咕音樂爬取

某種意義上講好久都沒有進行網站分析了,這次心血來潮,就分享一下如何從一個音樂網站的爬取數據的過程吧。內容可能會比較繁瑣,希望你耐心一點,做的不好的地方請多多包涵。

我們先從網站分析開始……
在這裏插入圖片描述
百度一下“咪咕音樂”,然後進入官網,依舊推薦使用谷歌瀏覽器進行網站解析。
其實也是聽舍友說咪咕上面歌比較多又是免費,貌似挺多人都喜歡周杰倫的,所以這次就來談談究竟,能不能爬到男神的歌呢?
在這裏插入圖片描述
按快捷鍵F12就可以進入開發者工具模式,或者鼠標右鍵點檢查元素。
注意要用到的兩個工具,相信抓包大家都會吧。要是不會的話可以繼續往下看。
element是審查網頁元素的,network可以實時抓取流經瀏覽器的數據。如果打開的時候數據不多,可是F5刷新一下,數據包就會重新加載進來啦。

在這裏插入圖片描述
你最好選上這個preserve log ,保留歷史數據,不然等會點到其他鏈接可能什麼都沒了,要重新分析。方框中的一攬子選項是過濾所需數據內容的,我們這次着重關注XHR,JS 和Media 。
在這裏插入圖片描述
在這裏插入圖片描述
你可以將鼠標懸浮在想要看的網頁位置上然後右鍵檢查元素,就會自動跳出該部件的所在網站源碼。我們按上面的操作選“晴天”然後右鍵,就可以看到有晴天這首歌的網址鏈接,但是這次的爬取和它沒有關係。

順帶介紹一下判斷網站傳輸數據方式的小技巧,當不知道自己是要爬網站還是抓取json包時,我們看看網頁的源代碼,注意是右鍵查看網頁源代碼,這個可和審查元素就不一樣了,審查元素往往你需要的數據都不在網頁源代碼裏面。
我們把審查元素裏獨有的一些值,比如歌曲id這種,然後轉到網頁源代碼,ctrl + F 快捷鍵打開查找框,輸入歌曲id,看看有沒有這個數據。
有那就表明我們可以直接爬取網頁獲取數據,我們的工作量會大大減少,否則你就要祈禱你能不能在抓包中獲得你想要的數據了。

在這裏插入圖片描述
因爲要爬歌曲,總得有個入口吧,就看看這首歌的播放鍵有沒有指向什麼鏈接。
很不幸只是用javascript加密過的鏈接,看到這個js其實可以宣告我們的分析失敗了,必須要換條路走。
不過我頭鐵,當時分析的時候還是想看看最後下載的歌曲鏈接有沒有什麼規律,這樣也是一種方法吧。於是……
在這裏插入圖片描述
這裏是點擊播放之後會彈出的網站,這個估計是咪咕的獨家祕訣,跳轉到它自己的播放網址下,可以擋掉一堆爬蟲了。
你可以看到要是直接點下載可是要登錄的,我當然還是喜歡悶聲發大財,哈哈開玩笑,不登錄照樣下載的下來。我們在這裏抓包一下,直接就找到了這個歌曲的鏈接,複製那一長串到新窗口試試,還真的有歌,還可以另存爲。
這要登錄才能下載的作用何在?!
我幫大家分析過了,這個歌曲的鏈接都是不同的,都被後臺加密過,所以暫時找不到規律,厲害的朋友可以試試,看能不能破解這鏈接的奧祕。
我當時人都傻掉了,出師未捷身先死啊……
在這裏插入圖片描述
不怕我突然想到另外一種方法:
既然咪咕的網頁版不行,那我們就用手機版的嘛,嘿嘿。
點擊左上角紅框處,然後刷新就會出現手機版的咪咕音樂。手機版的數據包往往比電腦版的容易獲得,你可以作爲一個經驗記下。
查看XHR很容易就找到了這個鏈接!

在這裏插入圖片描述
我們點Preview預覽一下,果然有歌曲哎,而且是典型的json格式,別高興得太早,要看看裏面有沒有我們要的歌曲鏈接。
在這裏插入圖片描述
打開網站查看內容,還真的有歌曲鏈接,而且都能用。雖然後來證實與網頁版的歌曲數不一樣,不過既然能爬那就是好事!接下來就剩下寫代碼和調試的問題啦。

import requests
import json
#import pprint


class Migu:
    def __init__(self,singer,headers):
        self.singer = singer
        self.headers = headers
        self.song_list = []
    def download(self,url,name):
        response = requests.get(url,headers=self.headers)
        with open('miguMusic/'+name+'.mp3','wb') as f:
            f.write(response.content)
        print(name,'下載成功')

    def get_every_url(self):
        index=1
        while True:
            try:
                url='http://m.music.migu.cn/migu/remoting/scr_search_tag?rows=20&type=2&keyword={}&pgc={}'.format(self.singer,index)
                response = requests.get(url,headers=self.headers)
                self.json_parse(response.text)
            except:
                break
            index+=1
    def json_parse(self,response):
        data = json.loads(response)
        #pprint.pprint(data)
        for every in data['musics']:
            self.song_list.append((every['mp3'],every['songName']))
            
    def main(self):
        self.get_every_url()
        for url,name in self.song_list:
            self.download(url,name)
            

if __name__=='__main__':
    headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
    }
    singer = input('請輸入歌手名:')
    migu = Migu(singer,headers)
    print('開始爬取音樂……')
    migu.main()
    print('爬取結束')

這次就一次性給到大家,結構很清晰,註釋後面補上,有些晚了該睡覺了,祝大家五一節快樂!
喜歡就點個贊吧!

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