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

引言css

通過前面兩節的學習,咱們學會了使用urllib去模擬請求,使用 Beautiful Soup正則表達式來處理網頁以獲取咱們須要的數據。 對於常常重複用到的代碼,咱們都會單獨抽取成本身的模塊, 好比代理池模塊:自動爬代理,校驗代理ip是否可用,存取ip, 又或者文件下載等,手撕爬蟲代碼是挺爽的蛤!不過今天並不用 手撕爬蟲,而是學習一個很出名的爬蟲框架——Scrapy(西瓜皮)。html


1.官方文檔與簡介

官方文檔docs.scrapy.org/en/latest/python

簡介web

Scrapy,諧音西瓜皮,Python開發的一個快速、高層次的屏幕抓取和 web抓取框架,用於抓取web站點並從頁面中提取結構化的數據。 Scrapy用途普遍,能夠用於數據挖掘、監測和自動化測試。正則表達式

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


2.Scrapy安裝

  • Window

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

鍵入下述命令進行安裝架構

conda install scrapy
複製代碼

安裝完成後,後面想執行Scrapy相關命令均可以在這裏執行:框架

  • Ubuntu

系統與Python版本Ubuntu 14.04      Python 3.4scrapy

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的架構圖

各個模塊的介紹

  • 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了。

使用示例

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

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**文件進行編輯,好比我這裏只須要兩個 字段,圖片的標題以及連接:

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

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

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

3.存儲數據

獲得咱們的結果啦,最簡單的存儲數據的方式就是使用Feed exports, 支持四種導出格式:JSON,JSON lines,XML和CSV 使用也很簡單,只是在平時執行scrapy腳本的後面加點東西:

scrapy crawl spider名字 -o 導出文件名 -t 導出格式
複製代碼

好比我這裏導出xml:

輸出結果:

4.下載圖片

圖片URL都有了,接下來確定是把圖片都download到本地啦~ 這裏就能夠直接使用Scrapy中內置的**ImagePipeline**啦!

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

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

接着命令行運行咱們的spider

scrapy crawl pic_spider
複製代碼

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

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


6.小結

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


參考文獻


來啊,Py交易啊

想加羣一塊兒學習Py的能夠加下,智障機器人小Pig,驗證信息裏包含: PythonpythonpyPy加羣交易屁眼 中的一個關鍵詞便可經過;

驗證經過後回覆 加羣 便可得到加羣連接(不要把機器人玩壞了!!!)~~~ 歡迎各類像我同樣的Py初學者,Py大神加入,一塊兒愉快地交流學♂習,van♂轉py。

相關文章
相關標籤/搜索