【scrapy】學習Scrapy入門

Scrapy介紹

Scrapy是一個為了爬取網(wǎng)站數(shù)據(jù)壹无,提取結構性數(shù)據(jù)而編寫的應用框架拍埠。 可以應用在包括數(shù)據(jù)挖掘,信息處理或存儲歷史數(shù)據(jù)等一系列的程序中速和。
所謂網(wǎng)絡爬蟲,就是一個在網(wǎng)上到處或定向抓取數(shù)據(jù)的程序剥汤,當然颠放,這種說法不夠?qū)I(yè),更專業(yè)的描述就是吭敢,抓取特定網(wǎng)站網(wǎng)頁的HTML數(shù)據(jù)碰凶。抓取網(wǎng)頁的一般方法是,定義一個入口頁面,然后一般一個頁面會有其他頁面的URL欲低,于是從當前頁面獲取到這些URL加入到爬蟲的抓取隊列中辕宏,然后進入到新頁面后再遞歸的進行上述的操作,其實說來就跟深度遍歷或廣度遍歷一樣砾莱。
Scrapy 使用 Twisted這個異步網(wǎng)絡庫來處理網(wǎng)絡通訊瑞筐,架構清晰,并且包含了各種中間件接口腊瑟,可以靈活的完成各種需求聚假。

整體架構

  • 引擎(Scrapy Engine),用來處理整個系統(tǒng)的數(shù)據(jù)流處理扫步,觸發(fā)事務魔策。
  • 調(diào)度器(Scheduler)匈子,用來接受引擎發(fā)過來的請求河胎,壓入隊列中,并在引擎再次請求的時候返回虎敦。
  • 下載器(Downloader)游岳,用于下載網(wǎng)頁內(nèi)容,并將網(wǎng)頁內(nèi)容返回給蜘蛛其徙。
  • 蜘蛛(Spiders)胚迫,蜘蛛是主要干活的,用它來制訂特定域名或網(wǎng)頁的解析規(guī)則唾那。編寫用于分析response并提取item(即獲取到的item)或額外跟進的URL的類访锻。 每個spider負責處理一個特定(或一些)網(wǎng)站。
  • 項目管道(Item Pipeline)闹获,負責處理有蜘蛛從網(wǎng)頁中抽取的項目期犬,他的主要任務是清晰、驗證和存儲數(shù)據(jù)避诽。當頁面被蜘蛛解析后龟虎,將被發(fā)送到項目管道,并經(jīng)過幾個特定的次序處理數(shù)據(jù)沙庐。
  • 下載器中間件(Downloader Middlewares)鲤妥,位于Scrapy引擎和下載器之間的鉤子框架,主要是處理Scrapy引擎與下載器之間的請求及響應拱雏。
  • 蜘蛛中間件(Spider Middlewares)棉安,介于Scrapy引擎和蜘蛛之間的鉤子框架,主要工作是處理蜘蛛的響應輸入和請求輸出铸抑。
  • 調(diào)度中間件(Scheduler Middlewares)贡耽,介于Scrapy引擎和調(diào)度之間的中間件,從Scrapy引擎發(fā)送到調(diào)度的請求和響應。

爬取流程

上圖綠線是數(shù)據(jù)流向菇爪,首先從初始URL開始算芯,Scheduler會將其交給Downloader進行下載,下載之后會交給Spider進行分析凳宙,Spider分析出來的結果有兩種:一種是需要進一步抓取的鏈接熙揍,例如之前分析的“下一頁”的鏈接,這些東西會被傳回Scheduler氏涩;另一種是需要保存的數(shù)據(jù)届囚,它們則被送到Item Pipeline那里,那是對數(shù)據(jù)進行后期處理(詳細分析是尖、過濾意系、存儲等)的地方。另外饺汹,在數(shù)據(jù)流動的通道里還可以安裝各種中間件蛔添,進行必要的處理。

數(shù)據(jù)流

Scrapy中的數(shù)據(jù)流由執(zhí)行引擎控制兜辞,其過程如下:

  1. 引擎打開一個網(wǎng)站(open a domain)迎瞧,找到處理該網(wǎng)站的Spider并向該spider請求第一個要爬取的URL(s)。
  2. 引擎從Spider中獲取到第一個要爬取的URL并在調(diào)度器(Scheduler)以Request調(diào)度逸吵。
  3. 引擎向調(diào)度器請求下一個要爬取的URL凶硅。
  4. 調(diào)度器返回下一個要爬取的URL給引擎,引擎將URL通過下載中間件(請求(request)方向)轉(zhuǎn)發(fā)給下載器(Downloader)扫皱。
  5. 一旦頁面下載完畢足绅,下載器生成一個該頁面的Response,并將其通過下載中間件(返回(response)方向)發(fā)送給引擎韩脑。
  6. 引擎從下載器中接收到Response并通過Spider中間件(輸入方向)發(fā)送給Spider處理氢妈。
  7. Spider處理Response并返回爬取到的Item及(跟進的)新的Request給引擎。
  8. 引擎將(Spider返回的)爬取到的Item給Item Pipeline扰才,將(Spider返回的)Request給調(diào)度器允懂。
  9. (從第二步)重復直到調(diào)度器中沒有更多地request,引擎關閉該網(wǎng)站衩匣。

Scrapy項目基本流程

默認的Scrapy項目結構

使用全局命令startproject創(chuàng)建項目蕾总,在project_name文件夾下創(chuàng)建一個名為project_name的Scrapy項目。

scrapy startproject myproject

雖然可以被修改琅捏,但所有的Scrapy項目默認有類似于下邊的文件結構:

scrapy.cfg
myproject/
    __init__.py
    items.py
    pipelines.py
    settings.py
    spiders/
        __init__.py
        spider1.py
        spider2.py
        ...

scrapy.cfg 存放的目錄被認為是 項目的根目錄 生百。該文件中包含python模塊名的字段定義了項目的設置。

定義要抓取的數(shù)據(jù)

Item 是保存爬取到的數(shù)據(jù)的容器柄延;其使用方法和python字典類似蚀浆, 并且提供了額外保護機制來避免拼寫錯誤導致的未定義字段錯誤缀程。
類似在ORM中做的一樣,您可以通過創(chuàng)建一個 scrapy.Item 類市俊, 并且定義類型為 scrapy.Field 的類屬性來定義一個Item杨凑。
首先根據(jù)需要從dmoz.org(DMOZ網(wǎng)站是一個著名的開放式分類目錄(Open DirectoryProject),由來自世界各地的志愿者共同維護與建設的最大的全球目錄社區(qū))獲取到的數(shù)據(jù)對item進行建模摆昧。 我們需要從dmoz中獲取名字撩满,url,以及網(wǎng)站的描述绅你。 對此伺帘,在item中定義相應的字段。編輯items.py 文件:

import scrapy

class DmozItem(scrapy.Item):
    title = scrapy.Field()
    link = scrapy.Field()
    desc = scrapy.Field()

使用項目命令genspider創(chuàng)建Spider

scrapy genspider [-t template] <name> <domain>

在當前項目中創(chuàng)建spider忌锯。
這僅僅是創(chuàng)建spider的一種快捷方法伪嫁。該方法可以使用提前定義好的模板來生成spider。您也可以自己創(chuàng)建spider的源碼文件偶垮。

$ scrapy genspider -l
Available templates:
  basic
  crawl
  csvfeed
  xmlfeed

$ scrapy genspider -d basic
import scrapy

class $classname(scrapy.Spider):
    name = "$name"
    allowed_domains = ["$domain"]
    start_urls = (
        'http://www.$domain/',
        )

    def parse(self, response):
        pass

$ scrapy genspider -t basic example example.com
Created spider 'example' using template 'basic' in module:
  mybot.spiders.example

編寫提取item數(shù)據(jù)的Spider

Spider是用戶編寫用于從單個網(wǎng)站(或者一些網(wǎng)站)爬取數(shù)據(jù)的類张咳。
其包含了一個用于下載的初始URL,如何跟進網(wǎng)頁中的鏈接以及如何分析頁面中的內(nèi)容针史, 提取生成 item 的方法晶伦。
為了創(chuàng)建一個Spider碟狞,您必須繼承 scrapy.Spider 類啄枕,且定義以下三個屬性:

  • name: 用于區(qū)別Spider。 該名字必須是唯一的族沃,您不可以為不同的Spider設定相同的名字频祝。
  • start_urls: 包含了Spider在啟動時進行爬取的url列表。 因此脆淹,第一個被獲取到的頁面將是其中之一常空。 后續(xù)的URL則從初始的URL獲取到的數(shù)據(jù)中提取。
  • parse() 是spider的一個方法盖溺。 被調(diào)用時漓糙,每個初始URL完成下載后生成的 Response 對象將會作為唯一的參數(shù)傳遞給該函數(shù)。 該方法負責解析返回的數(shù)據(jù)(response data)烘嘱,提取數(shù)據(jù)(生成item)以及生成需要進一步處理的URL的 Request 對象昆禽。
import scrapy

class DmozSpider(scrapy.spider.Spider):
    name = "dmoz"   #唯一標識,啟動spider時即指定該名稱
    allowed_domains = ["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(filename, 'wb') as f:
            f.write(response.body)

進行爬取

執(zhí)行項目命令crawl蝇庭,啟動Spider:

scrapy crawl dmoz

在這個過程中:
Scrapy為Spider的 start_urls 屬性中的每個URL創(chuàng)建了 scrapy.Request 對象醉鳖,并將 parse 方法作為回調(diào)函數(shù)(callback)賦值給了Request。
Request對象經(jīng)過調(diào)度哮内,執(zhí)行生成 scrapy.http.Response 對象并送回給spider parse() 方法盗棵。

通過選擇器提取數(shù)據(jù)

Selectors選擇器簡介:
Scrapy提取數(shù)據(jù)有自己的一套機制。它們被稱作選擇器(seletors),因為他們通過特定的 XPath 或者 CSS 表達式來“選擇” HTML文件中的某個部分纹因。
XPath 是一門用來在XML文件中選擇節(jié)點的語言喷屋,也可以用在HTML上。 CSS 是一門將HTML文檔樣式化的語言瞭恰。選擇器由它定義逼蒙,并與特定的HTML元素的樣式相關連。

XPath表達式的例子和含義:

  • /html/head/title: 選擇HTML文檔中 <head> 標簽內(nèi)的 <title> 元素
  • /html/head/title/text(): 選擇上面提到的 <title> 元素的文字
  • //td: 選擇所有的 <td> 元素
  • //div[@class="mine"]: 選擇所有具有 class="mine" 屬性的 div 元素

提取數(shù)據(jù):
觀察HTML源碼并確定合適的XPath表達式寄疏。
在查看了網(wǎng)頁的源碼后是牢,您會發(fā)現(xiàn)網(wǎng)站的信息是被包含在 第二個 <ul> 元素中。
我們可以通過這段代碼選擇該頁面中網(wǎng)站列表里所有 <li> 元素:
response.xpath('//ul/li')

Item 對象是自定義的python字典陕截。 您可以使用標準的字典語法來獲取到其每個字段的值驳棱。
一般來說,Spider將會將爬取到的數(shù)據(jù)以 Item 對象返回农曲。所以為了將爬取的數(shù)據(jù)返回社搅,我們最終的代碼將是:

import scrapy

from tutorial.items import DmozItem

class DmozSpider(scrapy.Spider):
    name = "dmoz"
    allowed_domains = ["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):
        for sel in response.xpath('//ul/li'):
            item = DmozItem()
            item['title'] = sel.xpath('a/text()').extract()
            item['link'] = sel.xpath('a/@href').extract()
            item['desc'] = sel.xpath('text()').extract()
            yield item

現(xiàn)在對dmoz.org進行爬取將會產(chǎn)生 DmozItem 對象。

保存數(shù)據(jù)

最簡單存儲爬取的數(shù)據(jù)的方式是使用 Feed exports:

scrapy crawl dmoz -o items.json

該命令將采用 JSON 格式對爬取的數(shù)據(jù)進行序列化乳规,生成 items.json 文件形葬。
如果需要對爬取到的item做更多更為復雜的操作,您可以編寫 Item Pipeline 暮的。類似于我們在創(chuàng)建項目時對Item做的笙以,用于您編寫自己的 tutorial/pipelines.py 也被創(chuàng)建。不過如果您僅僅想要保存item冻辩,您不需要實現(xiàn)任何的pipeline猖腕。

補充提示:Windows平臺安裝Scrapy的特別要求

Windows specific installation notes
Windows平臺下,安裝Scrapy之前首先要進行以下操作:

  • 安裝OpenSSL
    Win32 OpenSSL page中下載安裝Visual C++ 2008 redistributables和對應的OpenSSL安裝包恨闪,并把其可執(zhí)行文件目錄“*\openssl-win32\bin”加入到環(huán)境變量Path中
  • 安裝Scrapy依賴的二進制包
    pywin32
    Twisted
    zope.interface
    lxml
    pyOpenSSL

小結

第一篇關于Scrapy的文章主要依據(jù)Scrapy 0.24的中文文檔倘感,了解、熟悉Scrapy的使用和基本概念咙咽,在后面的相關文章中老玛,將進一步加入自己的思考和自行編寫的程序,期待能在這個過程中提高自己钧敞,也希望能對看到這些文章的讀者有用蜡豹。

參考資料

Scrapy架構概覽
初窺Scrapy
Scrapy入門教程
如何入門 Python 爬蟲

轉(zhuǎn)載請注明作者Jason Ding及其出處
Github博客主頁(http://jasonding1354.github.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
簡書主頁(http://www.reibang.com/users/2bd9b48f6ea8/latest_articles)

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市犁享,隨后出現(xiàn)的幾起案子余素,更是在濱河造成了極大的恐慌,老刑警劉巖炊昆,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件桨吊,死亡現(xiàn)場離奇詭異威根,居然都是意外死亡,警方通過查閱死者的電腦和手機视乐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門洛搀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人佑淀,你說我怎么就攤上這事留美。” “怎么了伸刃?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵谎砾,是天一觀的道長。 經(jīng)常有香客問我捧颅,道長景图,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任碉哑,我火速辦了婚禮挚币,結果婚禮上,老公的妹妹穿的比我還像新娘扣典。我一直安慰自己妆毕,他們只是感情好,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布贮尖。 她就那樣靜靜地躺著笛粘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪远舅。 梳的紋絲不亂的頭發(fā)上闰蛔,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機與錄音图柏,去河邊找鬼。 笑死任连,一個胖子當著我的面吹牛蚤吹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播随抠,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼裁着,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拱她?” 一聲冷哼從身側(cè)響起二驰,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎秉沼,沒想到半個月后桶雀,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矿酵,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年矗积,在試婚紗的時候發(fā)現(xiàn)自己被綠了全肮。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡棘捣,死狀恐怖辜腺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乍恐,我是刑警寧澤评疗,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站茵烈,受9級特大地震影響壤巷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瞧毙,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一胧华、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宙彪,春花似錦矩动、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至男图,卻和暖如春示姿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背逊笆。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工栈戳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人难裆。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓子檀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親乃戈。 傳聞我的和親對象是個殘疾皇子褂痰,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容

  • scrapy學習筆記(有示例版) 我的博客 scrapy學習筆記1.使用scrapy1.1創(chuàng)建工程1.2創(chuàng)建爬蟲模...
    陳思煜閱讀 12,696評論 4 46
  • scrapy是python最有名的爬蟲框架之一,可以很方便的進行web抓取症虑,并且提供了很強的定制型缩歪,這里記錄簡單學...
    bomo閱讀 2,115評論 1 11
  • 這兩天摸索了下scrapy,剛看文檔的時候覺得有點生無可戀谍憔,scrapy框架個人還是覺得比較難懂的匪蝙,需要學習的地方...
    Treehl閱讀 5,631評論 7 10
  • 眼下真是個“網(wǎng)紅”大爆發(fā)的年頭,一夜之間需忿,保持平庸若許年的田宗琦陡然就紅了诅炉,并且紅到了一衣帶水的東瀛日本。作...
    奧寺閱讀 3,182評論 0 0
  • 開始挑戰(zhàn)啦~~~學著輸出屋厘,首先我要讀"跟TED學表達"涕烧,這本書有很多TED的演講和演講時該注意的細節(jié),從表達情感汗洒,...
    全欣全歷閱讀 178評論 0 0