引言:
經過前面兩節的學習,我們學會了使用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爬蟲框架初體驗](https://i.iter01.com/images/45c82d60428c383b8cc87be253175a48657c06bd5b18d3206efe1e1cf8aff861.png)
鍵入下述命令進行安裝
conda install scrapy
複製程式碼
安裝完成後,後面想執行Scrapy相關命令都可以在這裡執行:
![小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗](https://i.iter01.com/images/25f014d1459f70fb79baa2a560d10b7574a2b456661321dca3c4e3a31f52594b.png)
- 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爬蟲框架初體驗](https://i.iter01.com/images/634c887a03ce074ff3665487c19e282b14bbe7bd37d8ff54da7d817629b5e2af.png)
各個模組的介紹:
-
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 4:
Scheduler
返回下一個要爬取的URL給引擎
,引擎
將URL通過下載中介軟體
(請求Request方向)轉發給Downloader
; - Step 5:一旦頁面下載完成,
Downloader
生成一個該頁面的Response, 並將其通過下載中介軟體
(返回response方向)傳送給**引擎
**; - Step 6:
引擎
從Downloader
中接收Response並通過Spider中介軟體
(輸出方向)傳送給**Spider
**處理; - Step 7:
Spider
處理Response並返回爬取到的Item
及(跟進的新 的Request)給引擎
; - Step 8:
引擎
將(Spider返回的)爬取到的Item
給Item 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爬蟲框架初體驗](https://i.iter01.com/images/1dcf4a1231d054b11ae02f5b23b15e64bcc026135a4d0ebe233ec71550b129e4.png)
命令列鍵入:scrapy crawl pic_spider 執行PicSpider,執行完成後可以 看到,Spider已經把這兩個網站給扒下來了,厲害了:
![小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗](https://i.iter01.com/images/8cb8dcd0219404f59d6b1c0bd6ff78794ddccecc04965e868c6e2b449ed4cf56.png)
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爬蟲框架初體驗](https://i.iter01.com/images/2a24b33a1f3f081b0d016d453e844d1ec59a7326bb6ee0aecbceb5359e401f2d.png)
編寫完後著手來修改我們的PicSpider類,選用的網址是: www.win4000.com/meitu.html
F12看下網頁結構,圈住的就是我們的入手點和想要獲取的資料了:
![小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗](https://i.iter01.com/images/feb921fe9cfc3448b1ac9eb9272f85c908df0343a2a83bf15591071372a1a7db.png)
從tab_box開始一層層定位到我們想要的地方,不難寫出下面的程式碼:
![小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗](https://i.iter01.com/images/83af5ea54dd0a563425c18ad540cd57c10796d00df4f1ebfafb6c5914dbbdf32.png)
3.儲存資料
得到我們的結果啦,最簡單的儲存資料的方式就是使用Feed exports, 支援四種匯出格式:JSON,JSON lines,XML和CSV 使用也很簡單,只是在平時執行scrapy指令碼的後面加點東西:
scrapy crawl spider名字 -o 匯出檔名 -t 匯出格式
複製程式碼
比如我這裡匯出xml:
![小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗](https://i.iter01.com/images/ff596344a6cd972185f0574d7de5c55194808b566544445d785a566c6a3a2954.png)
輸出結果:
![小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗](https://i.iter01.com/images/ba55c34ce64290b6667f4ed8ca8416c918a31ae3cf58973a347dfcddbfa0b193.png)
4.下載圖片
圖片URL都有了,接下來肯定是把圖片都download到本地啦~
這裡就可以直接使用Scrapy中內建的**ImagePipeline
**啦!
我們另外實現ImagePipeline,做下url校驗,已經圖片生成規則, 把圖片下載到我們想下載的地方,編輯下pipelines.py,新增:
![小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗](https://i.iter01.com/images/d660972e589f63a021a2325358bc60d34326d43622590faba0ab9b96639d4197.png)
然後settings.py,找到ITEM_PIPELINES把註釋去掉,啟用pinelines, 把我們自定義的PicPipeLine加上,還有順道設定下下載圖片的存放位置:
![小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗](https://i.iter01.com/images/4a13e18fc8431dffe70b3ad640c35831c21b6b32cba073547387fcfd9a789dd4.png)
接著命令列執行我們的spider
scrapy crawl pic_spider
複製程式碼
圖片都嘩嘩嘩地下載到本地了:
![小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗](https://i.iter01.com/images/ee960c1dff4e2d42a111fb882d5e36c992b1d74723cbb430f08ec3d60107263a.png)
嘻嘻,略爽,比起之前那種手寫的方式~
6.小結
本節對Python裡很出名的爬蟲框架Scrapy進行了初步的學習 後面還會更深入地去了解Scrapy,這裡先放一放。下一節我們 學習的是通過自動化測試框架Selenium來爬取使用JS動態生成 資料的場景,敬請期待~
![小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗](https://i.iter01.com/images/236ae615ad4378896f71a8f8e241a11263bcc52cc40c9060fd79490191410f76.png)
參考文獻:
來啊,Py交易啊
想加群一起學習Py的可以加下,智障機器人小Pig,驗證資訊裡包含: Python,python,py,Py,加群,交易,屁眼 中的一個關鍵詞即可通過;
![小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗](https://i.iter01.com/images/6c5f70eab729fc2b49469666629d2c712785e7b45cf48652f44eb4e8850dbeca.png)
驗證通過後回覆 加群 即可獲得加群連結(不要把機器人玩壞了!!!)~~~ 歡迎各種像我一樣的Py初學者,Py大神加入,一起愉快地交流學♂習,van♂轉py。
![小豬的Python學習之旅 —— 4.Scrapy爬蟲框架初體驗](https://i.iter01.com/images/51aaf062acfd90ed5d7a6c13e5dfd77990436082af0e0c1e6db005c59850f866.gif)