官术网_书友最值得收藏!

3.3 使用爬蟲框架Scrapy

因為爬蟲應用程序的需求日益高漲,所以在市面中誕生了很多第三方開源爬蟲框架,其中Scrapy是一個為了爬取網(wǎng)站數(shù)據(jù)、提取結構性數(shù)據(jù)而編寫的專業(yè)框架。Scrapy框架的用途十分廣泛,可以用于數(shù)據(jù)挖掘、數(shù)據(jù)監(jiān)測和自動化測試等工作。本節(jié)將簡要講解爬蟲框架Scrapy的基本用法。

3.3.1 Scrapy框架基礎

框架Scrapy使用了Twisted異步網(wǎng)絡庫來處理網(wǎng)絡通信,其整體架構大致如圖3-9所示。

圖3-9 框架Scrapy的架構

在Scrapy框架中,主要包括如下所示的組件。

● 引擎(Scrapy Engine):來處理整個系統(tǒng)的數(shù)據(jù)流,會觸發(fā)框架核心事務。

● 調度器(Scheduler):用來獲取Scrapy發(fā)送過來的請求,然后將請求傳入隊列中,并在引擎再次請求的時候返回。調度器的功能是設置下一個要抓取的網(wǎng)址,并刪除重復的網(wǎng)址。

● 下載器(Downloader):建立在高效的異步模型Twisted之上,下載目標網(wǎng)址中的網(wǎng)頁內容,并將網(wǎng)頁內容返回給Scrapy Engine。

● 爬蟲(Spiders):功能是從特定的網(wǎng)頁中提取指定的信息,這些信息在爬蟲領域中被稱為實體(Item)。

● 項目管道(Pipeline):處理從網(wǎng)頁中提取的爬蟲實體。當使用爬蟲解析一個頁面后,會將實體發(fā)送到項目管道中進行處理,然后驗證實體的有效性,并將不需要的信息刪除。

● 下載器中間件(Downloader Middlewares):此模塊位于Scrapy引擎和Downloader之間,為Scrapy引擎與下載器之間的請求及響應建立橋梁。

● 爬蟲中間件(Spider Middlewares):此模塊在Scrapy引擎和Spiders之間,功能是處理爬蟲的響應輸入和請求輸出。

● 調度中間件(Scheduler Middewares):在Scrapy引擎和Scheduler之間,表示從Scrapy引擎發(fā)送到調度的請求和響應。

在使用Scrapy框架后,下面是大多數(shù)爬蟲程序的運行流程。

1)Scrapy Engine從調度器中取出一個URL鏈接,這個鏈接作為下一個要抓取的目標。

2)Scrapy Engine將目標URL封裝成一個Request請求并傳遞給下載器,下載器在下載URL資源后,將資源封裝成Response應答包。

3)使用爬蟲解析Response應答包,如果解析出Item實體,則將結果交給實體管道進行進一步的處理。如果是URL鏈接,則把URL交給Scheduler等待下一步的抓取操作。

3.3.2 搭建Scrapy環(huán)境

在本地計算機安裝Python后,可以使用pip命令或easy_install命令來安裝Scrapy,具體命令格式如下所示。

另外,需要確保已安裝了“win32api”模塊,同時必須安裝與本地Python版本相對應的版本和位數(shù)(32位或64位)。讀者可以登錄http://www.lfd.uci.edu/~gohlke/pythonlibs/找到需要的版本,如圖3-10所示。

圖3-10 下載“win32api”模塊

下載后將得到一個“.whl”格式的文件,定位到此文件的目錄,然后通過如下命令安裝“win32api”模塊。

注意:如果遇到“ImportError: DLL load failed: 找不到指定的模塊。”錯誤,需要將“Python\Python35\Lib\site-packages\win32”目錄中的如下文件保存到本地系統(tǒng)盤中的“Windows\System32”目錄下。

● pythoncom36.dll。

● pywintypes36.dll。

3.3.3 創(chuàng)建第一個Scrapy項目

下面的實例代碼演示了創(chuàng)建第一個Scrapy項目的過程。

源碼路徑:daima\3\3-5\

(1)創(chuàng)建項目

在開始爬取數(shù)據(jù)之前,必須先創(chuàng)建一個新的Scrapy項目。進入準備存儲代碼的目錄中,然后運行如下所示的命令。

上述命令的功能是創(chuàng)建一個包含下列內容的“tutorial”目錄。

對上述文件的具體說明如下所示。

● scrapy.cfg:項目的配置文件。

● tutorial/:該項目的python模塊,之后在此加入代碼。

● tutorial/items.py:項目中的item文件。

● tutorial/pipelines.py:項目中的pipelines文件。

● tutorial/settings.py:項目的設置文件。

● tutorial/spiders/:放置spider代碼的目錄。

(2)定義Item

Item是保存爬取到的數(shù)據(jù)的容器,使用方法與Python字典類似,并且提供額外保護機制,避免拼寫錯誤導致未定義的字段錯誤。在實際應用中可以創(chuàng)建一個scrapy.Item類,并且定義類型為scrapy.Field。

首先需要從dmoz.org獲取數(shù)據(jù)對item進行建模。需要從dmoz中獲取名稱、url以及網(wǎng)站的描述。對此,在Item中定義相應的字段。編輯“tutorial”目錄中的文件items.py,具體實現(xiàn)代碼如下所示。

通過定義Item,可以很方便地使用Scrapy中的其他方法。而這些方法需要知道Item的定義。

(3)編寫第一個爬蟲(Spider)

Spider是用戶編寫用于從單個網(wǎng)站(或者一些網(wǎng)站)爬取數(shù)據(jù)的類,其中包含一個用于下載的初始URL,如何跟進網(wǎng)頁中的鏈接和如何分析頁面中的內容以及提取生成Item的方法。為了創(chuàng)建一個Spider,必須繼承類scrapy.Spider,且定義如下所示的三個屬性。

● name:用于區(qū)別Spider。該名稱必須是唯一的,因此不可以為不同的Spider設定相同的名稱。

● start_urls:包含了Spider在啟動時進行爬取的url列表。因此,第一個被獲取到的頁面將是其中之一。后續(xù)的URL則從初始的URL獲取到的數(shù)據(jù)中提取。

● parse():spider的一個方法。被調用時,每個初始URL完成下載后生成的Response對象將會作為唯一的參數(shù)傳遞給該方法。它負責解析返回的數(shù)據(jù)(response data),提取數(shù)據(jù)(生成Item)以及生成需要進一步處理的URL的Request對象。

下面是我們編寫的第一個Spider代碼,保存在tutorial/spiders目錄下的文件dmoz_spider.py中,具體實現(xiàn)代碼如下所示。

(4)爬取

進入項目的根目錄,執(zhí)行下列命令啟動spider。

crawl dmoz是負責啟動用于爬取dmoz.org網(wǎng)站的Spider,之后得到如下所示的輸出。

查看包含dmoz的輸出,可以看到在輸出的log中包含定義在start_urls的初始URL,并且與spider一一對應。在log中可以看到它沒有指向其他頁面(referer:None)。同時創(chuàng)建兩個包含url所對應的內容的文件:Book和Resources。

由此可見,Scrapy為Spider的start_urls屬性中的每個URL創(chuàng)建了scrapy.Request對象,并將Parse方法作為回調函數(shù)(callback)賦值給Request。Request對象經(jīng)過調度,執(zhí)行生成scrapy.http.Response對象并送回給spider parse()方法。

(5)提取Item

有很多種從網(wǎng)頁中提取數(shù)據(jù)的方法,Scrapy使用了一種基于XPath和CSS表達式機制:Scrapy Selectors。關于Selector和其他提取機制的信息,建議讀者參考Selector的官方文檔。下面給出XPath表達式的例子及對應的含義:

● /html/head/title:選擇HTML文檔中<head>標簽內的<title>元素。

● /html/head/title/text():選擇<title>元素的文字。

● //td:選擇所有的<td>元素。

● //div[@class="mine"]:選擇所有具有class="mine"屬性的div元素。

上面僅僅列出了幾個簡單的XPath例子,XPath的功能實際上要強大很多。為了配合XPath,Scrapy除了提供Selector之外,還提供了多個方法來避免每次從Response中提取數(shù)據(jù)時生成Selector的麻煩。

在Selector中有如下4個最基本的方法。

● xpath():用于選取指定的標簽內容,例如下面的代碼表示選取所有的book標簽。

● css():傳入CSS表達式,用于選取指定的CSS標簽內容。

● extract():返回選中內容的Unicode字符串,返回結果是列表。

● re():根據(jù)傳入的正則表達式提取數(shù)據(jù),返回Unicode字符串格式的列表。

● re_first():返回SelectorList對象中的第一個Selector對象調用的re方法。

使用內置的Scrapy shell,首先需要進入本實例項目的根目錄,然后執(zhí)行如下命令來啟動Shell。

此時shell將會輸出類似如下所示的內容。

載入Shell后得到一個包含Response數(shù)據(jù)的本地Response變量。輸入“response.body”命令后會輸出Response的包體,輸入“response.headers”后可以看到Response的包頭。更為重要的是,當輸入“response.selector”時,將獲取一個可以用于查詢返回數(shù)據(jù)的Selector(選擇器),以及映射到response.selector.xpath()、response.selector.css()的快捷方法(shortcut):response.xpath()和response.css()。同時,Shell根據(jù)Response提前初始化了變量sel。該Selector根據(jù)Response的類型自動選擇最合適的分析規(guī)則(XML vs HTML)。

(6)提取數(shù)據(jù)

接下來嘗試從這些頁面中提取有用數(shù)據(jù),只需在終端中輸入response.body來觀察HTML源碼并確定合適的XPath表達式。但這個任務非常無聊且不易,可以考慮使用Firefox的Firebug擴展來簡化工作。

查看網(wǎng)頁源碼后會發(fā)現(xiàn)網(wǎng)站的信息被包含在第二個<ul>元素中。可以通過下面的代碼選擇該頁面中網(wǎng)站列表里的所有<li>元素。

通過如下命令獲取對網(wǎng)站的描述。

通過如下命令獲取網(wǎng)站的標題。

3.3.4 抓取某電影網(wǎng)的熱門電影信息

本實例的功能是,使用Scrapy爬蟲抓取某電影網(wǎng)中熱門電影信息。

源碼路徑:daima\3\3-6\

1)在具體爬取數(shù)據(jù)之前,必須先創(chuàng)建一個新的Scrapy項目。首先進入準備保存項目代碼的目錄中,然后運行如下所示的命令。

2)編寫文件moviedouban.py設置要爬取的URL范圍和過濾規(guī)則,主要實現(xiàn)代碼如下所示。

3)編寫執(zhí)行腳本文件pyrequests_douban.py,功能是編寫功能函數(shù)獲取熱門電影的詳細信息,包括電影名、URL鏈接地址、導演信息、主演信息等。文件pyrequests_douban.py的主要實現(xiàn)代碼如下所示。

執(zhí)行后會輸出顯示爬取到的熱門電影信息,如圖3-11所示。

圖3-11 爬取到的熱門電影信息

3.3.5 抓取某網(wǎng)站中的照片并保存到本地

本實例的功能是使用Scrapy爬蟲抓取某網(wǎng)站中的照片信息,并將抓取到的照片保存到本地硬盤中。編寫文件art.py設置要爬取的URL范圍和抓取的內容元素,主要實現(xiàn)代碼如下所示。

源碼路徑:daima\3\3-7\

執(zhí)行后會顯示抓取目標網(wǎng)站圖片的過程,如圖3-12所示。

圖3-12 網(wǎng)站圖片抓取過程

將抓取到的照片保存到本地文件夾“download_images”中,如圖3-13所示。

圖3-13 在本地硬盤保存抓取到的圖片

3.3.6 抓取某網(wǎng)站中的主播照片并保存到本地

本實例的功能是使用Scrapy爬蟲抓取某網(wǎng)站中的主播照片,并將抓取到的主播照片保存到本地硬盤中。編寫文件douyu.py設置要爬取的URL范圍和抓取的內容元素,設置要抓取的Item(是主播昵稱和主播照片)。文件douyu.py的主要實現(xiàn)代碼如下所示。

源碼路徑:daima\3\3-8\

執(zhí)行后會將抓取到的主播照片保存到本地文件夾中,如圖3-14所示。

圖3-14 抓取到的主播照片

主站蜘蛛池模板: 天峻县| 柳河县| 东辽县| 荥阳市| 淮北市| 洛宁县| 泗水县| 东乡族自治县| 浪卡子县| 封开县| 大丰市| 紫阳县| 肇源县| 武隆县| 凉城县| 小金县| 浑源县| 灵宝市| 乌苏市| 天长市| 隆安县| 鹤庆县| 临武县| 丽江市| 赤城县| 清流县| 祁东县| 桐梓县| 镇坪县| 轮台县| 锡林郭勒盟| 五大连池市| 漳浦县| 桐乡市| 沁源县| 尼勒克县| 聂拉木县| 固安县| 锦州市| 呼和浩特市| 湾仔区|