Python爬蟲小白——(二)爬蟲基礎——Selenium PhantomJS
前段時間嘗試爬取了網易雲音樂的歌曲,這次打算爬取QQ音樂的歌曲資訊。網易雲音樂歌曲列表是通過iframe展示的,可以藉助Selenium獲取到iframe的頁面元素,
而QQ音樂採用的是非同步載入的方式,套路不一樣,這是主流的頁面載入方式,爬取有點難度,不過也是對自己的一個挑戰。
二、Python爬取QQ音樂單曲
之前看的慕課網的一個視訊, 很好地講解了一般編寫爬蟲的步驟,我們也按這個來。
爬蟲步驟
1.確定目標
首先我們要明確目標,本次爬取的是QQ音樂歌手劉德華的單曲。
(百度百科)->分析目標(策略:url格式(範圍)、資料格式、網頁編碼)->編寫程式碼->執行爬蟲
2.分析目標
歌曲連結:https://y.qq.com/n/yqq/singer/003aQYLo2x8izP.html#tab=song&
從左邊的截圖可以知道單曲採用分頁的方式排列歌曲資訊,每頁顯示30條,總共30頁。點選頁碼或者最右邊的">"會跳轉到下一頁,瀏覽器會向伺服器傳送ajax非同步請求,從連結可以看到begin和num引數,分別代表起始歌曲下標(截圖是第2頁,起始下標是30)和一頁返回30條,伺服器響應返回json格式的歌曲資訊(MusicJsonCallbacksinger_track({"code":0,"data":{"list":[{"Flisten_count1":......]})),如果只是單獨想獲取歌曲資訊,可以直接拼接連結請求和解析返回的json格式的資料。這裡不採用直接解析資料格式的方法,我採用的是Python Selenium方式,每獲取和解析完一頁的單曲資訊,點選 ">" 跳轉到下一頁繼續解析,直至解析並記錄所有的單曲資訊。最後請求每個單曲的連結,獲取詳細的單曲資訊。
右邊的截圖是網頁的原始碼,所有歌曲資訊都在類名為mod_songlist的div浮層裡面,類名為songlist_list的無序列表ul下,每個子元素li展示一個單曲,類名為songlist__album下的a標籤,包含單曲的連結,名稱和時長等。
3.編寫程式碼
1)下載網頁內容,這裡使用Python 的Urllib標準庫,自己封裝了一個download方法:
def download(url, user_agent='wswp', num_retries=2):
2)解析網頁內容,這裡使用第三方外掛BeautifulSoup,具體可以參考BeautifulSoup API 。
def music_scrapter(html, page_num=0):
def get_music():
4.執行爬蟲
爬蟲跑起來了,一頁一頁地去爬取專輯的連結,並儲存到集合中,最後通過get_music()方法獲取單曲的名稱,連結,歌手名稱和時長並儲存到Excel檔案中。
原始碼 群 960410445
三、Python爬取QQ音樂單曲總結
1.單曲採用的是分頁方式,切換下一頁是通過非同步ajax請求從伺服器獲取json格式的資料並渲染到頁面,瀏覽器位址列連結是不變的,不能通過拼接連結來請求。一開始想過都通過Python Urllib庫來模擬ajax請求,後來想想還是用Selenium。Selenium能夠很好地模擬瀏覽器真實的操作,頁面元素定位也很方便,模擬單擊下一頁,不斷地切換單曲分頁,再通過BeautifulSoup解析網頁原始碼,獲取單曲資訊。
2.url連結管理器,採用集合資料結構來儲存單曲連結,為什麼要使用集合?因為多個單曲可能來自同一專輯(專輯網址一樣),這樣可以減少請求次數。
class UrlManager(object):
def add_new_url(self, url):
3.通過Python第三方外掛openpyxl讀寫Excel十分方便,把單曲資訊通過Excel檔案可以很好地儲存起來。
def write_to_excel(self, content):
四、後語
最後還是要慶祝下,畢竟成功把QQ音樂的單曲資訊爬取下來了。本次能夠成功爬取單曲,Selenium功不可沒,這次只是用到了selenium一些簡單的功能,後續會更加深入學習Selenium,不僅在爬蟲方面還有UI自動化。
後續還需要優化的點:
1.下載的連結比較多,一個一個下載起來比較慢,後面打算用多執行緒併發下載。
2.下載速度過快,為了避免伺服器禁用IP,後面還要對於同一域名訪問過於頻繁的問題,有個等待機制,每個請求之間有個等待間隔。
3. 解析網頁是一個重要的過程,可以採用正則表示式,BeautifulSoup和lxml,目前採用的是BeautifulSoup庫, 在效率方面,BeautifulSoup沒lxml效率高,後面會嘗試採用lxml。