Scrapy介绍及入门
?
?一、Scrapy簡介
? ? ? ?Scrapy是一個為了爬取網(wǎng)站數(shù)據(jù),提取結構性數(shù)據(jù)而編寫的應用框架。 可以應用在包括數(shù)據(jù)挖掘,信息處理或存儲歷史數(shù)據(jù)等一系列的程序中。
? ? ? 其最初是為了頁面抓取 (更確切來說, 網(wǎng)絡抓取 )所設計的, 也可以應用在獲取API所返回的數(shù)據(jù)(例如 Amazon Associates Web Services ) 或者通用的網(wǎng)絡爬蟲。
二、架構概覽
1. Scrapy Engine
? ? ? ?引擎負責控制數(shù)據(jù)流在系統(tǒng)中所有組件中流動,并在相應動作發(fā)生時觸發(fā)事件。 詳細內容查看下面的數(shù)據(jù)流(Data Flow)部分。此組件相當于爬蟲的“大腦”,是整個爬蟲的調度中心。
2. 調度器(Scheduler)
? ? ? ? 調度器從引擎接受request并將他們入隊,以便之后引擎請求他們時提供給引擎。
? ? ? ?初始的爬取URL和后續(xù)在頁面中獲取的待爬取的URL將放入調度器中,等待爬取。同時調度器會自動去除重復的URL(如果特定的URL不需要去重也可以通過設置實現(xiàn),如post請求的URL)
3. 下載器(Downloader)
? ? ? ? 下載器負責獲取頁面數(shù)據(jù)并提供給引擎,而后提供給spider。
4. Spiders
? ? ? ? Spider是Scrapy用戶編寫用于分析response并提取item(即獲取到的item)或額外跟進的URL的類。 每個spider負責處理一個特定(或一些)網(wǎng)站。
5. Item Pipeline
? ? ? ?Item Pipeline負責處理被spider提取出來的item。典型的處理有清理、 驗證及持久化(例如存取到數(shù)據(jù)庫中)。
? ? ? ?當頁面被爬蟲解析所需的數(shù)據(jù)存入Item后,將被發(fā)送到項目管道(Pipeline),并經(jīng)過幾個特定的次序處理數(shù)據(jù),最后存入本地文件或存入數(shù)據(jù)庫。
6. 下載器中間件(Downloader middlewares)
? ? ? ?下載器中間件是在引擎及下載器之間的特定鉤子(specific hook),處理Downloader傳遞給引擎的response。 其提供了一個簡便的機制,通過插入自定義代碼來擴展Scrapy功能。通過設置下載器中間件可以實現(xiàn)爬蟲自動更換user-agent、IP等功能。
7. Spider中間件(Spider middlewares)
? ? ? ?Spider中間件是在引擎及Spider之間的特定鉤子(specific hook),處理spider的輸入(response)和輸出(items及requests)。 其提供了一個簡便的機制,通過插入自定義代碼來擴展Scrapy功能。
8. 數(shù)據(jù)流(Data flow)
? ? ? ?1) 引擎打開一個網(wǎng)站(open a domain),找到處理該網(wǎng)站的Spider并向該spider請求第一個要爬取的URL(s)。
? ? ? ?2) 引擎從Spider中獲取到第一個要爬取的URL并在調度器(Scheduler)以Request調度。
? ? ? ?3) 引擎向調度器請求下一個要爬取的URL。
? ? ? ?4) 調度器返回下一個要爬取的URL給引擎,引擎將URL通過下載中間件(請求(request)方向)轉發(fā)給下載器(Downloader)。
? ? ??5) 一旦頁面下載完畢,下載器生成一個該頁面的Response,并將其通過下載中間件(返回(response)方向)發(fā)送給引擎。
? ? ?? 6) 引擎從下載器中接收到Response并通過Spider中間件(輸入方向)發(fā)送給Spider處理。
? ? ? ?7) Spider處理Response并返回爬取到的Item及(跟進的)新的Request給引擎。
? ? ? ?8) 引擎將(Spider返回的)爬取到的Item給Item Pipeline,將(Spider返回的)Request給調度器。
? ? ? ?9) (從第二步)重復直到調度器中沒有更多地request,引擎關閉該網(wǎng)站。
三、創(chuàng)建項目
? ? ? ?在開始抓取之前,你必須建立一個新的零碎項目。輸入要在其中存儲代碼并運行的目錄:
?? ? ?創(chuàng)建了一個tutorial目錄包含以下內容:
四、創(chuàng)建第一只sipder
? ? ? ?爬行器是定義的類,Scrapy使用它從一個網(wǎng)站(或一組網(wǎng)站)中抓取信息。它們必須是子類 Spider 并定義要做出的初始請求,可選的是如何跟隨頁面中的鏈接,以及如何解析下載的頁面內容以提取數(shù)據(jù)。
? ? ? ?創(chuàng)建第一只spider的代碼。將其保存在tutorial/spiders 項目命名文件為quotes_spider.py中:
? ? ? ?Spider子類 scrapy.Spider 并定義了一些屬性和方法:
? ? ? ?name :標識spider。它在一個項目中必須是唯一的,即不能為不同的爬行器設置相同的名稱。
? ? ? ?start_requests() :必須返回請求的可迭代(可以返回請求列表或編寫生成器函數(shù)),爬行器將從該請求開始爬行。后續(xù)請求將從這些初始請求中相繼生成。
? ? ? ?parse() :將被調用以處理為每個請求下載的響應的方法。Response參數(shù)是 TextResponse 它保存頁面內容,并具有進一步有用的方法來處理它。
? ? ? ?這個 parse() 方法通常解析響應,將抓取的數(shù)據(jù)提取為字典,還查找要遵循的新URL并創(chuàng)建新請求 (Request )。
? ? 運行創(chuàng)建的sipder,此命令運行我們剛剛添加的spider quotes,這將發(fā)送一些 quotes.toscrape.com 領域。您將得到類似于以下內容的輸出:
?? ? ? 現(xiàn)在,檢查當前目錄中的文件。您應該注意到已經(jīng)創(chuàng)建了兩個新文件: quotes-1.html 和 quotes-2.HTML, 將各個URL的內容作為 parse 方法指示。
?五、提取數(shù)據(jù)
? ? ? ?? ?scrappy提取數(shù)據(jù)的最佳方法是使用 Scrapy shell :
? ? ? ?使用shell,可以嘗試使用 CSS 對于響應對象:
? ? ? ?要從上述標題中提取文本,可以執(zhí)行以下操作:
? ? ? ?這里有兩件事需要注意:一是我們已經(jīng)添加了 ::text 對于CSS查詢,意味著我們只想直接選擇內部的文本元素 <title> 元素。如果我們不指定 ::text ,我們將獲得完整的title元素,包括其標記:
? ? ? ?另一件事是呼叫的結果 .getall() 是一個列表:選擇器可能返回多個結果,因此我們提取所有結果。只想要第一個結果時,如本例所示:
? ? ? ?作為替代,可以寫下:
?? ? ? 使用 .get() 直接在A上 SelectorList 實例避免了 IndexError 回報 None 當它找不到任何與所選內容匹配的元素時。
? ? ? ?除 getall() 和 get() 方法以外,也可以使用 re() 提取方法 regular expressions :
? ? ? ?除 CSS外 ,scrapy選擇器也支持使用 XPath 表達
? ? ? ?XPath表達式是非常強大的,是抓取選擇器的基礎。實際上,CSS選擇器在引擎蓋下轉換為xpath。xpath表達式提供了更多的功能,因為除了導航結構之外,它還可以查看內容。使用xpath,您可以選擇如下內容:*選擇包含文本“下一頁”*的鏈接,這使得xpath非常適合于抓取任務。
六、提取引用和作者
? ? ? ?編寫代碼從網(wǎng)頁中提取引號來完成spider程序。http://quotes.toscrape.com中的每個引號都由如下所示的HTML元素表示:
? ? ? ?打開Scrapy Shell并提取所需數(shù)據(jù):
? ? ? 得到了一個quote HTML元素的選擇器列表,其中包括:
? ? ? ?上面查詢返回的每個選擇器都允許對其子元素運行進一步的查詢。將第一個選擇器分配給一個變量,這樣我們就可以直接在特定的引號上運行CSS選擇器:
? ? ? ?提取 text , author以及 tags,其中tags是字符串列表,我們可以使用 .getall() 方法獲取所有這些參數(shù):
? ? ? ?提取每個位之后,迭代所有的quotes元素,并將它們放在Python字典中:
? ? ? 在spider中提取數(shù)據(jù),使用 yield 回調response中的python關鍵字,如下所示:
? ? ? ?存儲抓取的數(shù)據(jù),最簡單方法是使用 Feed exports ,使用以下命令:
? ? ? 這將生成一個 quotes.json 包含所有抓取的項目的文件,序列化在 JSON 。
? ? ? ?這個 -O 命令行開關覆蓋任何現(xiàn)有文件;使用 -o 而是將新內容附加到任何現(xiàn)有文件中。但是,附加到JSON文件會使文件內容無效JSON。附加到文件時,請考慮使用不同的序列化格式,例如 JSON Lines ::
? ? ? ?JSON Lines 類似于流,可以很容易地向它附加新記錄。當運行兩次時,它不存在相同的JSON問題。另外,由于每個記錄都是單獨的一行,可以處理大文件,而不必將所有內容都放入內存中,因此有如下工具: JQ以幫助在命令行中執(zhí)行此操作。
? ? ? ?從網(wǎng)站上所有頁面的引用抓取內容。從頁面中跟蹤鏈接第一件事是提取到要跟蹤的頁面的鏈接。檢查頁面,可以看到有一個鏈接指向下一個帶有以下標記的頁面:
? ? ? ?在外殼中提取:
? ? ? ?獲取到anchor元素,但需要該屬性href ,Scrapy支持CSS擴展,允許選擇屬性內容,如下所示:
? ? ? ?還有一個 attrib 可用屬性
? ? ? ?將spider被修改為遞歸地跟蹤下一頁的鏈接,從中提取數(shù)據(jù):
? ? ? 在提取數(shù)據(jù)之后, parse() 方法查找到下一頁的鏈接,并使用 urljoin() 方法(因為鏈接可以是相對的),并生成對下一頁的新請求,將自身注冊為回調,以處理下一頁的數(shù)據(jù)提取,并保持爬行在所有頁中進行。
? ? ? ?scrapy的以下鏈接機制:在回調方法中生成一個請求時,scrapy將計劃發(fā)送該請求,并注冊一個回調方法,以便在該請求完成時執(zhí)行。
? ? ? ?使用它可以構建復雜的爬蟲程序,這些爬蟲程序根據(jù)定義的規(guī)則跟蹤鏈接,并根據(jù)所訪問的頁面提取不同類型的數(shù)據(jù)。
? ? ? ?示例中,創(chuàng)建了一種循環(huán),跟蹤到下一頁的所有鏈接,直到找不到一個為止——這對于爬行博客、論壇和其他帶有分頁的站點很方便。
七、創(chuàng)建請求的快捷方式
? ? ? ?作為創(chuàng)建請求對象的快捷方式,可以使用 response.follow ::
? ? ? ?不像Scrapy.Request, response.follow 直接支持相對URL-無需調用URLJOIN。注意response.follow 只返回一個請求實例;仍然需要生成這個請求。
? ? ? ?也可以將選擇器傳遞給 response.follow 而不是字符串;此選擇器應提取必要的屬性:
? ? ? ?為了 <a> 元素有一個快捷方式: response.follow 自動使用其href屬性。因此代碼可以進一步縮短:
? ? ? ?要從iterable創(chuàng)建多個請求,可以使用 response.follow_all 取而代之的是:
? ? ? ?進一步縮短:
? ? ? ?另一個spider,演示回調和以下鏈接,抓取作者信息:
? ? ? ? 這個spider將從主頁開始,跟蹤所有指向作者頁面的鏈接,調用 parse_author 它們的回調,以及與 parse 像我們以前看到的那樣回撥。
?? ? ? ?在這里,我們將回調傳遞給 response.follow_all 作為位置參數(shù),以使代碼更短;它還適用于 Request 。
? ? ? ?這個 parse_author 回調定義了一個助手函數(shù),用于從CSS查詢中提取和清理數(shù)據(jù),并用作者數(shù)據(jù)生成python dict。
? ? ? ?這個spider展示的另一個有趣的事情是,即使同一作者引用了很多話,我們也不需要擔心多次訪問同一作者頁面。默認情況下,scrapy過濾掉對已經(jīng)訪問過的URL的重復請求,避免了由于編程錯誤而太多地訪問服務器的問題。這可以通過設置進行配置 DUPEFILTER_CLASS .
八、使用spider參數(shù)
? ? ? ?通過使用 -a 運行它們時的選項:
? ? ? ?這些論點被傳給spider?__init__ 方法并默認成為spider屬性。
? ? ? ?在本例中,為 tag 參數(shù)將通過 self.tag 。可以使用它的spider只獲取帶有特定標記的引號,并基于以下參數(shù)構建URL::
? ? ????????? ? 如果你通過 tag=humor 對于這個spider,您會注意到它只訪問來自 humor 標記,如 http://quotes.toscrape.com/tag/humor .
總結
以上是生活随笔為你收集整理的Scrapy介绍及入门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python爬虫介绍及实战入门
- 下一篇: VALSE 视觉资源汇总(视频+PPT+