協作閣

開源協作部落格

爬蟲經驗小記錄

Yulin / 2019-06-14 /


以下都是根據我個人少少的爬蟲經驗的心得(aka一堆廢話),認真爬完網站、抓到自己需要且乾淨的資料大概只有三次。其他不少次都是爬一爬,心裡卻只有一個想法:「X北,這什麼網站!?也太難爬了吧。」然後就放棄了。 但隨著對網頁架構的知識和學到的技巧越來越多,才發現其實根本不是人家難爬,是自己太菜。

背景知識

最重要的當然是知道html的架構,知道要用什麼tag、class之類的來選擇要爬的資料。這篇文章簡單介紹了一下概念。更詳細的概念、更進階的技巧可以參考這份投影片。 我最初也只知道css selector,但後來用了selenium才發現其實也可以用其他的方法定位網頁元素,可以用XPath、link text,甚至partial text也可以。

搜尋相關資源

這是一個很重要但可能無幫助的步驟,原因在於自己的程式能力太弱,就算搜到看起來可用的代碼,也會因為看不懂而不知道到底該怎麼改。不過有時候還是可以從中得到一些洞見、突破一些盲點。舉例如之前看到別人用的套件,才發現原來我要爬的資料可以用不登入的方式爬到,其實就藏在原始碼裡面(這邊要感謝Sean火眼金睛)。

正式開爬前

上面是我寫爬蟲程式時給自己設定的原則,因此通常我花最多時間的地方是解析網站架構,找到我要的資料到底被放在網頁的何處,接著規劃自己的程式流程。而且有時候因為網站架構很複雜,很容易會迷失在層層結構之中,所以一開始就一步一步寫好切入的流程,有助於後面寫程式的時候確定自己走在正確的路上,而且一步一步完成的感覺超爽的XD

通常我會把每一步驟寫出來,最後再統合出需要的函式。如下所示:

chrome agent: >a) 進入父話題 > 點完全部的「更多鍵」> 取得全頁html > get每個子話題的連結(存到一個list裡面) >b) 進入子話題 > 選擇「精華」> 滾軸下滑兩次 > 取得全頁html > get每個問題的連結(存到另一個list) >c) 進入問題 > 爬取”問題標題”,“關注者”,“被瀏覽數”,“話題標籤”,“發布時間”

需要的function: >- selenium: 1)進入話題 2)點擊更多 3)滾輪下滑 4)取得全頁html >- bs: 1)丟入element以get連結 2)爬取

開爬注意事項

比較好爬的網站通常只需要用到requests,再用美麗的湯解析,就很快可以爬到自己要的資料了。然而,就是有些網站真的很優秀(例如ㄓㄏ呵呵),讓我有了研究selenium怎麼用的機會。此外也隨著需要爬取的資料量越來越大,必須注意的事情也越多了。以下僅列出由個人經驗總結出的幾項:

1. 定時或定量機制

出於爬蟲禮儀(?),要記得設定user agent,而且不可以一下子爬太快或太多。目前我使用過的方法都是sleep,個人認為這種作法最保險,但缺點就是會花費較多時間。如果有其他防被偵測到或防被吉的好方法,罷偷教我。

2. 用來提示自己的訊息

因為以前爬的網站資料量都不大,也沒在預期以外的地方遇到什麼古怪的bug,所以我一直沒有這個提示自己的習慣。但隨著程式步驟逐漸複雜,且要爬的資料量越來越大,我們需要在過程中印出一些訊息來提示自己現在爬到哪個地方、還有多久可以爬完,讓自己知道現在究竟進行到哪一步了,也方便針對問題debug。

if i % 500 == 0:    #設定每爬500筆就回傳進度並存檔
    print(f'已經爬了{i}/{len(all_questions)}個問題囉')
    with open('results_temp.json', 'w') as f:
        json.dump(results, f, ensure_ascii=False, indent=4)

3. 存檔

因為要爬的資料量很大,所以最好邊爬邊存,以免到時候發生意外要全部重來,很浪費時間。

4. 用regex撈資料的時候一定要寫註解!

先前爬了某虎購物網站,寫re不寫註解,後來要改又花了很多時間研究自己到底在寫什麼。之後爬公司法,還是死不寫註解,現在我又忘記那時候寫的re到底是什麼意思…

前三點都是這次爬較大量資料的新心得(這邊順便感謝所上巨巨Richard幫我很多忙,回答我很多白癡問題)。第四點就是個人慘痛經驗,也算是知道了絕對不要相信自己的記憶力。

要補的洞

1. Server指令

用Server遠端跑程式可以解放自己的人身和筆電自由,而且最近有一些雲端Server產品可以用,暑假一定要來好好研究一下。(主要也是因為巨巨要畢業了,我也必須獨立了XD)

2. 分布式爬蟲

一種可以大大縮短爬蟲時間但聽起來很高端艱深的爬蟲實踐,但概念其實就像把一份任務分割成n個小任務,然後湊齊n台電腦,接著這n台電腦同時分別去執行各自的任務,有點像並聯的概念。基礎作法需要研究的套件有urllib和redis,更高效的作法需要研究Scrapy。

爬蟲蠻有趣的,爬完的時候總會對「我全都要」這句話有深刻感受。 但有時候也真的令人頭痛。