小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

coder-pig發表於2017-12-29

引言

經過前面兩節的學習,我們學會了使用urllib去模擬請求,使用 Beautiful Soup正規表示式來處理網頁以獲取我們需要的資料。 對於經常重複用到的程式碼,我們都會單獨抽取成自己的模組, 比如代理池模組:自動爬代理,校驗代理ip是否可用,存取ip, 又或者檔案下載等,手撕爬蟲程式碼是挺爽的蛤!不過今天並不用 手撕爬蟲,而是學習一個很出名的爬蟲框架——Scrapy(西瓜皮)。


1.官方文件與簡介

官方文件docs.scrapy.org/en/latest/

簡介

Scrapy,諧音西瓜皮,Python開發的一個快速、高層次的螢幕抓取和 web抓取框架,用於抓取web站點並從頁面中提取結構化的資料。 Scrapy用途廣泛,可以用於資料探勘、監測和自動化測試。

Scrapy吸引人的地方在於它是一個框架,任何人都可以根據需求 方便的修改。它也提供了多種型別爬蟲的基類,如BaseSpider、 sitemap爬蟲等,最新版本又提供了web2.0爬蟲的支援。


2.Scrapy安裝

  • Window

網上的安裝教程都很繁瑣,偶然間發現一種傻瓜式的,直接安裝:Anaconda 選擇對應的windows版本,然後傻瓜式下一步就可以了,安裝完成後, 點選開始找到並開啟:

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

鍵入下述命令進行安裝

conda install scrapy
複製程式碼

安裝完成後,後面想執行Scrapy相關命令都可以在這裡執行:

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

  • Ubuntu

系統與Python版本Ubuntu 14.04      Python 3.4

sudo pip3 install Scrapy
複製程式碼

中途出現一個錯誤:fatal error: 'Python.h' file not found 需要另外安裝python-dev,該庫中包含Python的標頭檔案與靜態庫包, 要根據自己的Python版本進行安裝:

sudo apt-get install python3.4-dev
複製程式碼
  • Mac

系統與Python版本OS 10.13.2      Python 3.6

pip install Scrapy
複製程式碼

3.Scrapy框架的大概瞭解


Scrapy的架構圖

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

各個模組的介紹

  • Scrapy Engine(Scrapy引擎) 核心,負責控制資料流在系統中所有的元件中流動, 並在相應的動作發生時觸發事件。

  • Scheduler(排程器) 從引擎接受 request 並讓其入隊,以便之後引擎請求 它們時提供給引擎。

  • Downloader(下載器) 獲取頁面資料並提供給引擎,而後提供給Spider。

  • Spiders(蜘蛛...) 編寫用於分析由下載器返回的response,並提取出item 和額外跟進的URL的類。

  • Item Pipeline(專案管道) 負責處理處理被Spider提取出來的item。常見的處理有: 清理、驗證和持久化。

  • Download Middlewares(下載器中介軟體) 引擎與下載器間的特定鉤子,處理下載器傳遞給引擎的Response。

  • Spider Middlewares(Spider中介軟體) 引擎與Spider間的特定鉤子,處理Spider輸入(下載器的Response)和 輸出(傳送給items給Item Pipeline,以及傳送Request給排程器)

執行流程

  • Step 1引擎開啟一個網站,找到處理該網站的Spider並向該Spider 請求第一個要爬取的URL;
  • Step 2引擎Spider中獲取到第一個要爬取的URL,並在Scheduler 以Request排程;
  • Step 3:**引擎Scheduler**請求下一個要爬取的URL;
  • Step 4Scheduler返回下一個要爬取的URL給引擎引擎將URL通過 下載中介軟體(請求Request方向)轉發給Downloader
  • Step 5:一旦頁面下載完成,Downloader生成一個該頁面的Response, 並將其通過下載中介軟體(返回response方向)傳送給**引擎**;
  • Step 6引擎Downloader中接收Response並通過Spider中介軟體 (輸出方向)傳送給**Spider**處理;
  • Step 7Spider處理Response並返回爬取到的Item及(跟進的新 的Request)給引擎
  • Step 8引擎將(Spider返回的)爬取到的ItemItem Pipeline, 將(Spider返回的)Request給**Scheduler**;
  • Step 9:繼續重複從Step2開始,直到**Scheduler裡沒有更多的Request, 然後引擎**關閉該網站。

4.新建並瞭解Scrapy專案結構

執行下述命令可以生成一個Scrapy專案

scrapy startproject 專案名
複製程式碼

新建的專案結構如下

ScrapyStudy/
    scrapy.cfg            # 專案的配置檔案
    ScrapyStudy/          # 該專案的python模組,程式碼都加在裡面
        __init__.py
        items.py          # 專案中的item檔案
        pipelines.py      # 專案中pipelines檔案
        settings.py       # 專案的設定檔案
        spiders/          # 方式spider程式碼的目錄
            __init__.py
複製程式碼

5.Scrapy使用初體驗

1.編寫Spider類爬取到網頁

自定義Spider時,需 繼承scrapy.Spider類,且必須有以下三個成員:

  • name:用於區分不同的Spider,名字要唯一!!!
  • parse(response):Spider的一個回撥函式,當Downloader返回Response時會被呼叫, 每個初始URL完成下載後生成的response物件將會作為唯一的引數傳遞 給該函式。該函式負責解析返回的資料(response),提取資料(生成item) 以及生成需要進一步處理的URL的Request物件。
  • start_requests():Spider剛啟動時,生成需要爬去的連結,寫這個 就不用寫start_urls了。

使用示例

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

命令列鍵入:scrapy crawl pic_spider 執行PicSpider,執行完成後可以 看到,Spider已經把這兩個網站給扒下來了,厲害了:

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

2.取出網頁中想要的資訊

Scrapy中使用一種基於XPath和CSSDE表示式機制:Scrapy Selectors 來提取出網頁中我們所需的資料。

Selector是一個選擇,有四個基本方法:

  • xpath():傳入xpath表示式,返回該表示式對應的所有節點的selector list列表;
  • css():傳入CSS表示式,返回該表示式對應的所有及誒點的selector list列表;
  • extract():序列化該節點為unicode字串並返回list;
  • re():根據傳入的正規表示式對資料進行提取,返回unicode字串list列表;

這裡順道學下XPath的基本語法:(更多可見:www.w3school.com.cn/xpath/)

首先XPath中的路徑分為絕對路徑與相對路徑絕對路徑:用**/,表示從根節點開始選取; 相對路徑:用//,表示選擇任意位置的節點,而不考慮他們的位置; 另外可以使用*萬用字元來表示未知的元素;除此之外還有兩個選取節點的: .:選取當前節點;..**:當前節點的父節點;

接著就是選擇分支進行定位了,比如存在多個元素,想唯一定位, 可以使用**[]**中括號來選擇分支,下標是從1開始算的哦! 比如可以有下面這些玩法:

  • /tr/td[1]:取第一個td
  • /tr/td[last()]:取最後一個td
  • /tr/td[last()-1]:取倒數第二個td
  • /tr/td[position()<3]:取第一個和第二個td
  • /tr/td[@class]:選取擁有class屬性的td
  • /tr/td[@class='xxx']:選取擁有class屬性為xxx的td
  • /tr/td[count>10]:選取 price 元素的值大於10的td

然後是選擇屬性,其實就是上面的這個**@** 可以使用多個屬性定位,可以這樣寫:/tr/td[@class='xxx'][@value='yyy'] 或者**/tr/td[@class='xxx' and @value='yyy']**

再接著是常用函式:除了上面的last()position(),外還有: contains(string1,string2):如果前後匹配返回True,不匹配返回False; text():獲取元素的文字內容 start-with():從起始位置匹配字串 更多的自己去翻文件吧~

最後是,當上面的操作都不能定位時,這個時候可以考慮根據元素 的父輩節點或者兄弟節點來定位了,這個時候就會用到Xpath軸, 利用軸可定位某個相對於當前節點的節點集,語法:軸名稱::標籤名 規則列表如下:

軸名稱 作用
ancestor 選取當前節點的所有先輩(父、祖父等)。
ancestor-or-self 選取當前節點的所有先輩(父、祖父等)以及當前節點本身。
attribute 選取當前節點的所有屬性。
child 選取當前節點的所有子元素。
descendant 選取當前節點的所有後代元素(子、孫等)。
descendant-or-self 選取當前節點的所有後代元素(子、孫等)以及當前節點本身。
following 選取文件中當前節點的結束標籤之後的所有節點。
following-sibling 選取當前節點之後的所有兄弟節點
namespace 選取當前節點的所有名稱空間節點。
parent 選取當前節點的父節點。
preceding 選取文件中當前節點的開始標籤之前的所有節點。
preceding-sibling 選取當前節點之前的所有同級節點。
self 選取當前節點。

大概規則瞭解到這裡,接下來就用Xpath來獲取我們想要的東西~

在開始解析之前我們還要寫一個Item,就是拿來裝我們爬取篩選 過後資料的容器,使用方法和Python中的字典類似,並且提供了 額外的保護機制來避免因拼寫錯誤導致的未定義欄位錯誤。 開啟專案中的**items.py**檔案進行編輯,比如我這裡只需要兩個 欄位,圖片的標題以及連結:

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

編寫完後著手來修改我們的PicSpider類,選用的網址是: www.win4000.com/meitu.html

F12看下網頁結構,圈住的就是我們的入手點和想要獲取的資料了:

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

從tab_box開始一層層定位到我們想要的地方,不難寫出下面的程式碼:

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

3.儲存資料

得到我們的結果啦,最簡單的儲存資料的方式就是使用Feed exports, 支援四種匯出格式:JSON,JSON lines,XML和CSV 使用也很簡單,只是在平時執行scrapy指令碼的後面加點東西:

scrapy crawl spider名字 -o 匯出檔名 -t 匯出格式
複製程式碼

比如我這裡匯出xml:

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

輸出結果:

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

4.下載圖片

圖片URL都有了,接下來肯定是把圖片都download到本地啦~ 這裡就可以直接使用Scrapy中內建的**ImagePipeline**啦!

我們另外實現ImagePipeline,做下url校驗,已經圖片生成規則, 把圖片下載到我們想下載的地方,編輯下pipelines.py,新增:

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

然後settings.py,找到ITEM_PIPELINES把註釋去掉,啟用pinelines, 把我們自定義的PicPipeLine加上,還有順道設定下下載圖片的存放位置:

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

接著命令列執行我們的spider

scrapy crawl pic_spider
複製程式碼

圖片都嘩嘩嘩地下載到本地了:

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

嘻嘻,略爽,比起之前那種手寫的方式~


6.小結

本節對Python裡很出名的爬蟲框架Scrapy進行了初步的學習 後面還會更深入地去了解Scrapy,這裡先放一放。下一節我們 學習的是通過自動化測試框架Selenium來爬取使用JS動態生成 資料的場景,敬請期待~

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗


參考文獻


來啊,Py交易啊

想加群一起學習Py的可以加下,智障機器人小Pig,驗證資訊裡包含: PythonpythonpyPy加群交易屁眼 中的一個關鍵詞即可通過;

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗

驗證通過後回覆 加群 即可獲得加群連結(不要把機器人玩壞了!!!)~~~ 歡迎各種像我一樣的Py初學者,Py大神加入,一起愉快地交流學♂習,van♂轉py。

小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗


相關文章