2017年10月26日 星期四

2017.10.25 嘗試用Python爬蟲技巧抓混音音樂

2017.10.25 嘗試用Python抓混音音樂

這天JN在耍廢休息時瀏覽ptt時,又見到過去頗想收藏的音樂。比較可惜的是,音樂網站只有提供網路播放,並未提供下載按鈕。然而,JN堅信一點「只要能被人聽閱的影音,其檔案一定被下載進自己的電腦裡。」所以,JN相信,只要我能在網路上以正常方式聽閱的任何影音,絕對有方法給它給存下來。

根據之前學過的爬蟲技巧,第一步,先用chrome的Web Developer Tool(F12)並重新整理網頁後觀察。JN很快就發現了影片格式的檔案:mp4以及m4s。接著,打開其影音檔案來源網址,使用另存新檔的方式存下。

存下來的mp4具有正確的影音時間長度卻沒有任何音訊。m4s則為分割的許多片段,直接用影音播放器並不能播放,於是JN試著把副檔名改成mp4、mp3,亦得到同樣的結果:無法播放。


隨手求助google,打上「m4s 合併檔案」搜尋,不過搜尋的結果卻不是很滿意,前幾個結果內容所說的程式,從程式的官方網站看,卻得到程式碼,而不是直接能用並帶有介面的程式。不然就是被防毒軟體掃出有疑慮,最後找到的程式碼也並非JN所學過的程式語言。用英文搜尋也是差不多的答案。

不過雖然程式碼並非JN所學過的程式語言,但JN觀其架構是十分簡單的,其運作過程只是把mp4(開頭)以byte方式合併其他的m4s(片段),最後就能得到所想要目標影音檔案。如果是正常能播放的影音檔案,就能用剪接軟體。不過碰到byte合併的方式,寫程式碼就是最簡單的方法。

byte合併可以直接以字元提示命令去執行,但JN不是很熟這個,JN比較熟悉python,於是用python去寫。

當使用Web Developer Tool去看時,JN就發現影音片段(m4s)會隨時間下載後面的片段,並不會一開始就把全部的片段都下載完,這段於提升網頁瀏覽速度是很有幫助,不過卻苦了想直接下載一個完整檔案的人。觀察其片段的網址,各片段的網址取決於編號的不同,所以只需要改編號,就能抓到想要的片段。JN直接嘗試1000號片段,跑出結果404,只要超過片段數,就會抓到404網頁,然後看檔案大小就知道從哪一編號後的就是抓到404網頁。

要抓所有片段很簡單,只需要用迴圈產生各片段網址,然後用python的request套件去get各片段網址,得到「get的結果」,並且用python的shutil套件把「get的結果」存成m4s影音。這些技巧都是從網路教學的爬蟲影片學到的,JN在第一篇的python網誌有寫到從哪裡學到的。最後,JN當時所抓的片段有七百多個,每個平均90kb。

所要的檔案都齊了:開頭的mp4、所有的m4s片段,接下來就是要合起來了。

別忘了要以byte方式合併,JN用python內建的open函式,以wb的方式寫一個輸出檔案。程式碼如下。
AllFragments = open(output.mp4,'wb')
接著其他的片段,也是以open函式以'rb'來讀取,然後以read得到其byte數據。接下來,照順序以mp4的byte數據、以編號順序片段的byte數據,寫進輸出檔案裡。這樣就完成以byte方式合併所有片段了。

最後,用播放器打開輸出檔案,能夠播放,而且也與網路上所聽到的相同。直接跳到最後十秒測試,也沒有缺少音訊。這就是JN所想要的影音檔了。

後記:
JN猜測,其實合併各片段的程式碼,應該在第一步的時候就已經抓到了。猜測是程式語言javascript去做這次JN用python做的事情。但只是JN的功力不夠深厚,挖掘經驗太淺,沒辦法第一時間撈出來。希望有一天記得要再好好地把這個程式碼給揪出來,而不靠自己閉門造車。

會講混音音樂是個提示,並不是指各網站的混音音樂。

這個程式碼可以繼續寫成音樂爬蟲,能夠爬下所有的音樂並且合併輸出。不過JN觀察,該網站應該有下載流量限制,想快速抓完音樂需要有點技巧。