創建項目
在開始爬取之前,您必須創建一個新的Scrapy項目。進入您打算存儲代碼的目錄中,運行下列命令:
scrapy startproject tutorial
- 1
該命令行將會創建包含下列內容的tutorial
目錄:
tutorial/
scrapy.cfg
tutorial/
__init__.py
items.py
pipelines.py
settings.py
spiders/
__init__.py
...
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
這些文件分別是:
- scrapy.cfg:項目的配置文件
- tutorial:該項目的python模塊。之后您將在此加入代碼。
- tutorial/items.py:項目中的item文件。
- tutorial/pipelines.py:項目中的pipelines文件。
- tutorial/spiders/:放置spider代碼的目錄。
定義Item
Item是保存爬取到的數據的容器:其使用方法和python字典類似,並且提供了額外保護機制來避免拼寫錯誤導致的未定義字段錯誤。
類似在ORM中做的一樣,你可以通過創建一個scrapy.Item
類,並且定義類型為scrapy.Field
的類屬性來定義一個Item。
首先根據需要從dmoz.org獲取到的數據對item進行建模。我們需要從dmoz中獲取名字,url,以及網站的描述。對此,在item中定義相應的字段。編輯tutorial
目錄中的items.py
文件:
import scrapy class DmozItem(scrapy.Item): title=scrapy.Field() link=scrapy.Field() desc=scrapy.Field()
- 1
- 2
- 3
- 4
- 5
- 6
一開始這看起來可能有點復雜,但是通過定義item,您可以很方便的使用Scrapy的其他方法。而這些方法需要知道您的item定義
編寫第一個爬蟲(Spider)
Spider是用戶編寫用於從單個網站(或者一些網站)爬取數據的類。
其包含了一個用於下載的初始url,如何跟進網頁中的鏈接以及如何分析頁面中的內容,提取生成item的方法。
為了創建一個Spider,您必須繼承scrapy.Spider
類,且定義以下三個屬性:
name
:用於區別Spider。改名字必須是唯一的,您不可以為不同的Spider設定相同的名字。start_urls
:包含了Spider在啟動時進行爬取的url列表。因此,第一個被獲取的頁面給將是其中之一。后續的URL則從初始的URL獲取到的數據中提取。-
parse()
:是spider的一個方法。被調用時,每個初始url完成下載后生成的Response
對象將會作為唯一的參數傳遞給該函數。該方法負責解析返回的數據(response data),提取數據(生成item)以及生成需要進一步處理的URL的Request
對象。以下為我們第一個Spider代碼,保存在
tutorial/spiders
目錄下的dmoz_spider.py
文件中:
import scrapy class DmozSplider(scray.spiders.Spider): name="dmoz" allowed_domain=["dmoz.org"] start_urls=[ "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/", "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/" ] def parse(self,response): filename=response.url.split("/")[-2] with open(file,"wb") as f: f.write(response.body)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
爬取
進入項目的根目錄,執行下列命令啟動spider:
scrapy crawl dmoz
- 1
crawl dmoz
啟動用於爬取dmoz.org
的spider,您將得到類似的輸出:
2014-01-23 18:13:07-0400 [scrapy] INFO: Scrapy started (bot: tutorial) 2014-01-23 18:13:07-0400 [scrapy] INFO: Optional features available: ... 2014-01-23 18:13:07-0400 [scrapy] INFO: Overridden settings: {} 2014-01-23 18:13:07-0400 [scrapy] INFO: Enabled extensions: ... 2014-01-23 18:13:07-0400 [scrapy] INFO: Enabled downloader middlewares: ... 2014-01-23 18:13:07-0400 [scrapy] INFO: Enabled spider middlewares: ... 2014-01-23 18:13:07-0400 [scrapy] INFO: Enabled item pipelines: ... 2014-01-23 18:13:07-0400 [dmoz] INFO: Spider opened 2014-01-23 18:13:08-0400 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/> (referer: None) 2014-01-23 18:13:09-0400 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> (referer: None) 2014-01-23 18:13:09-0400 [dmoz] INFO: Closing spider (finished)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
查看包含dmoz
的輸出,可以看到輸出的log中包含定義在start_urls
的初始url,並且與splider中是一一對應的。在log中可以看到其沒有指向其他頁面(referer:None
)
除此之外,更有趣的事情發生了。就像我們parse
方法指定的那樣,這兩個包含url所對應的內容的文件被創建了:Book,Resources。
剛才發生了什么
Scrapy為Spider的start_urls
屬性中的每個url創建了scrapy.Request
對象,並將parse()
方法作為回調函數(callback)賦值給了Request
Request對象進過調度,執行生成scrapy.http.Response
對象並送回給Spiderparse()
方法