用Python爬取實習資訊(Scrapy初體驗)

發表於2016-10-19

1.目標

這兩天要弄一個大作業,從水木社群北大未名社群的實習板塊,爬取實習資訊,儲存在MongoDB資料庫。
正好想學習一下scrapy框架的使用,就愉快地決定用scrapy來實現。

2.介紹

Scrapy是Python開發的一個快速,高層次的螢幕抓取和web抓取框架,用於抓取web站點並從頁面中提取結構化的資料。使用了 Twisted 非同步網路庫來處理網路通訊。整體架構:

用Python爬取實習資訊(Scrapy初體驗)
學習使用Scrapy,最重要的是官方文件。本文的主要參考資料也是該文件。
Scrapy的安裝,這裡就不說了,在滿足一系列依賴的安裝以後,pip一下,就搞定了。

3.開始

3.1 首先,新建一個Scrapy工程。

進入你的目標目錄,輸入以下指令,建立專案intern。

目錄結構如下:

這個目錄結構要熟記於心。

  • scrapy.cfg: 全域性配置檔案
  • intern/: 專案python模組
  • intern/items.py: 專案items檔案,定義爬取的資料儲存結構
  • intern/pipelines.py: 專案管道檔案,對爬取來的資料進行清洗、篩選、儲存等操作
  • intern/settings.py: 專案配置檔案
  • intern/spiders: 放置spider的目錄

3.2 編寫items.py檔案。

定義item的欄位如下:

定義的方法很簡單,每個欄位都=scrapy.Field()即可。
使用:比如要使用某item的title,就像python中的dict一樣,item[‘title’]即可。

3.3 編寫爬蟲。

好了終於到了編寫爬蟲了。以爬取水木社群的爬蟲為例。在spiders目錄下,建立smSpider.py。

從淺到深,一步步解釋這段程式碼。
首先,這個SMSpider是繼承於CrawlSpider,CrawlSpider繼承於BaseSpider。一般用BaseSpider就夠了,CrawlSpider可以增加一些爬取的Rule。但實際上我這裡並沒有用到。必需要定義的三個屬性。
name:爬蟲的名字。(唯一)
start_url:爬蟲開始爬取的url列表。
parse():爬蟲爬取的方法。呼叫時傳入一個response物件,作為訪問某連結的響應。
在爬取水木社群的時候發現,水木的實習資訊是動態載入的。

用Python爬取實習資訊(Scrapy初體驗)

也就是說,原始碼中,並沒有我們要的實習資訊。這時,考慮使用Selenium和Phantomjs的配合。Selenium本來在自動化測試上廣泛使用,它可以模仿使用者在瀏覽器上的行為,比如點選按鈕等等。Phantomjs是一個沒有UI的瀏覽器。Selenium和Phantomjs搭配,就可以方便地抓取動態載入的頁面。

用Python爬取實習資訊(Scrapy初體驗)

回到SMSpider的程式碼,我們要判斷當前的作業系統平臺,然後在Selenium的webdriver中載入Phantomjs。Linux不用輸入路徑,Windows要輸入程式所在路徑。在init()的結尾,還要加上事件分發器,使得在爬蟲退出後,關閉Phantomjs。

這句程式碼是為了不讓Phantom卡死在某一連結的請求上。設定每個頁面載入時間不能超過10秒。
具體的parse方法:

這段程式碼,先是找到動態載入的目標標籤,等待這個標籤出現,再爬取實習資訊列表,再巢狀爬取每條實習資訊的具體內容。這裡我使用bs4對html進行解析。你也可以使用原生態的Xpath,或者selector。這裡就不進行具體的講解了,多瞭解幾種方法,熟練一種即可。爬取到的目標內容,像 item[‘title’] = title這樣,儲存在item裡。注意最後不是return,而是yeild。parse方法採用生成器的模式,逐條爬取分析。
爬取具體實習內容的程式碼:

3.4 編寫pipelines.py。

接下來,我們想把爬取到的資料,存在Mongodb裡面。這可以交給pipeline去做。pipeline是我喜歡Scrapy的一個理由,你可以把你爬到的資料,以item的形式,扔進pipeline裡面,進行篩選、去重、儲存或者其他自定義的進一步的處理。pipeline之間的順序,可以在settings.py中設定,這使得pipeline更加靈活。
來看看MongoDBPipeline:

來說明一下。
首先建立類MongoDBPipeline,這裡不用繼承什麼預先設定好的pipeline。但是要有一個process_item的方法,傳入一個item和spider,返回處理完的item。open_spider和close_spider是在爬蟲開啟和關閉的時候呼叫的回撥函式。這裡我們要用到MongoDB,所以我們在爬蟲開啟的時候,連線一個Mongo客戶端,在爬蟲關閉的時候,再把客戶端關掉。這裡的資料庫相關的資訊,都儲存在settings.py裡面。如下:

寫在settings.py裡面的引數可以通過

這種方式來獲取。
在寫完MongoDBPipeline以後,還要在settings.py註冊一下這個pipeline,如下:

後面的數值越小,越先執行。數值的範圍是1000以內的整數。通過這種方法,可以非常方便地設定pipeline之間的順序,以及開啟和關閉一個pipeline。

4.執行

在專案目錄下,執行如下指令:

這時我們的SMSpider就愉快地開始爬取資料了。

用Python爬取實習資訊(Scrapy初體驗)

5.下一步

關於scrapy框架,要學的還有很多。比如說擴充套件和中介軟體的編寫,以及Crawler API的使用。
關於爬蟲,可以學習的還有:

  • 使用代理
  • 模擬登陸

下面一段時間,要做新浪微博的爬蟲,屆時有新的收穫再和大家分享。
本文原始碼地址:github
喜歡star一下哦~~~~

相關文章