鍍金池/ 教程/ Python/ 初窺 Scrapy
Benchmarking
命令行工具(Command line tools)
下載器中間件(Downloader Middleware)
信號(Signals)
Telnet 終端(Telnet Console)
初窺 Scrapy
數(shù)據(jù)收集(Stats Collection)
Scrapyd
通用爬蟲(Broad Crawls)
Item Loaders
試驗(yàn)階段特性
Scrapy 入門教程
自動限速(AutoThrottle)擴(kuò)展
Settings
Scrapy 終端(Scrapy shell)
下載項(xiàng)目圖片
DjangoItem
調(diào)試(Debugging)Spiders
選擇器(Selectors)
Feed exports
Spiders Contracts
借助 Firefox 來爬取
Logging
Spiders
Ubuntu 軟件包
實(shí)踐經(jīng)驗(yàn)(Common Practices)
安裝指南
Item Exporters
擴(kuò)展(Extensions)
Items
Spider 中間件(Middleware)
異常(Exceptions)
例子
發(fā)送 email
架構(gòu)概覽
常見問題(FAQ)
Jobs:暫停,恢復(fù)爬蟲
核心 API
使用 Firebug 進(jìn)行爬取
Item Pipeline
Link Extractors
Web Service
調(diào)試內(nèi)存溢出

初窺 Scrapy

Scrapy 是一個為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應(yīng)用框架。 可以應(yīng)用在包括數(shù)據(jù)挖掘,信息處理或存儲歷史數(shù)據(jù)等一系列的程序中。

其最初是為了頁面抓取 (更確切來說,網(wǎng)絡(luò)抓取)所設(shè)計(jì)的, 也可以應(yīng)用在獲取 API 所返回的數(shù)據(jù)(例如 Amazon Associates Web Services ) 或者通用的網(wǎng)絡(luò)爬蟲。

本文檔將通過介紹 Scrapy 背后的概念使您對其工作原理有所了解, 并確定Scrapy是否是您所需要的。

當(dāng)您準(zhǔn)備好開始您的項(xiàng)目后,您可以參考入門教程。

選擇一個網(wǎng)站

當(dāng)您需要從某個網(wǎng)站中獲取信息,但該網(wǎng)站未提供API或能通過程序獲取信息的機(jī)制時,Scrapy 可以助你一臂之力。

Mininova 網(wǎng)站為例,我們想要獲取今日添加的所有種子的 URL、名字、描述以及文件大小信息。

今日添加的種子列表可以通過這個頁面找到:
http://www.mininova.org/today

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

第一步是定義我們需要爬取的數(shù)據(jù)。在 Scrapy 中, 這是通過 Scrapy Items 來完成的。(在本例子中為種子文件)

我們定義的 Item:

import scrapy

class TorrentItem(scrapy.Item):
    url = scrapy.Field()
    name = scrapy.Field()
    description = scrapy.Field()
    size = scrapy.Field()

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

第二步是編寫一個 spider。其定義了初始 URL(http://www.mininova.org/today)、針對后續(xù)鏈接的規(guī)則以及從頁面中提取數(shù)據(jù)的規(guī)則。

通過觀察頁面的內(nèi)容可以發(fā)現(xiàn),所有種子的 URL 都類似 http://www.mininova.org/tor/NUMBER 。 其中,NUMBER 是一個整數(shù)。 根據(jù)此規(guī)律,我們可以定義需要進(jìn)行跟進(jìn)的鏈接的正則表達(dá)式: /tor/\d+。

我們使用 XPath 來從頁面的HTML源碼中選擇需要提取的數(shù)據(jù)。 以其中一個種子文件的頁面為例:

http://www.mininova.org/tor/2676093

觀察 HTML 頁面源碼并創(chuàng)建我們需要的數(shù)據(jù)(種子名字,描述和大小)的 XPath 表達(dá)式。

通過觀察,我們可以發(fā)現(xiàn)文件名是包含在 <h1> 標(biāo)簽中的:

<h1>Darwin - The Evolution Of An Exhibition</h1>

與此對應(yīng)的 XPath 表達(dá)式:

//h1/text()

種子的描述是被包含在 id="description"<div>標(biāo)簽中:

<h2>Description:</h2>

<div id="description">
Short documentary made for Plymouth City Museum and Art Gallery regarding the setup of an exhibit about Charles Darwin in conjunction with the 200th anniversary of his birth.

...

對應(yīng)獲取描述的 XPath 表達(dá)式:

//div[@id='description']

文件大小的信息包含在 id=specifications<div>的第二個<p>標(biāo)簽中:

<div id="specifications">

<p>
<strong>Category:</strong>
<a href="/cat/4">Movies</a> &gt; <a href="/sub/35">Documentary</a>
</p>

<p>
<strong>Total size:</strong>
150.62&nbsp;megabyte</p>

選擇文件大小的 XPath 表達(dá)式:

//div[@id='specifications']/p[2]/text()[2]

關(guān)于 XPath 的詳細(xì)內(nèi)容請參考 XPath 參考 。

最后,結(jié)合以上內(nèi)容給出 spider 的代碼:

from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors import LinkExtractor

class MininovaSpider(CrawlSpider):

    name = 'mininova'
    allowed_domains = ['mininova.org']
    start_urls = ['http://www.mininova.org/today']
    rules = [Rule(LinkExtractor(allow=['/tor/\d+']), 'parse_torrent')]

    def parse_torrent(self, response):
        torrent = TorrentItem()
        torrent['url'] = response.url
        torrent['name'] = response.xpath("http://h1/text()").extract()
        torrent['description'] = response.xpath("http://div[@id='description']").extract()
        torrent['size'] = response.xpath("http://div[@id='info-left']/p[2]/text()[2]").extract()
        return torrent

TorrentItem 的定義在 上面 。

執(zhí)行 spider,獲取數(shù)據(jù)

終于,我們可以運(yùn)行 spider 來獲取網(wǎng)站的數(shù)據(jù),并以 JSON 格式存入到 scraped_data.json 文件中:

scrapy crawl mininova -o scraped_data.json

命令中使用了 Feed 導(dǎo)出 來導(dǎo)出 JSON 文件。您可以修改導(dǎo)出格式(XML 或者 CSV)或者存儲后端(FTP 或者 Amazon S3),這并不困難。

同時,您也可以編寫 item 管道 將 item 存儲到數(shù)據(jù)庫中。

查看提取到的數(shù)據(jù)

執(zhí)行結(jié)束后,當(dāng)您查看 scraped_data.json,您將看到提取到的 item:

[{"url": "http://www.mininova.org/tor/2676093", "name": ["Darwin - The Evolution Of An Exhibition"], "description": ["Short documentary made for Plymouth ..."], "size": ["150.62 megabyte"]},
# ... other items ...
]

由于 選擇器(Selectors) 返回 list,所以值都是以 list 存儲的(除了 url 是直接賦值之外)。 如果您想要保存單個數(shù)據(jù)或者對數(shù)據(jù)執(zhí)行額外的處理,那將是 Item Loaders 發(fā)揮作用的地方。

還有什么?

您已經(jīng)了解了如何通過 Scrapy 提取存儲網(wǎng)頁中的信息,但這僅僅只是冰山一角。Scrapy 提供了很多強(qiáng)大的特性來使得爬取更為簡單高效,例如:

  • HTML,XML 源數(shù)據(jù) 選擇及提取 的內(nèi)置支持
  • 提供了一系列在spider之間共享的可復(fù)用的過濾器(即 Item Loaders),對智能處理爬取數(shù)據(jù)提供了內(nèi)置支持。
  • 通過 feed 導(dǎo)出 提供了多格式(JSON、CSV、XML),多存儲后端(FTP、S3、本地文件系統(tǒng))的內(nèi)置支持
  • 提供了 media pipeline,可以 自動下載 爬取到的數(shù)據(jù)中的圖片(或者其他資源)。
  • 高擴(kuò)展性。您可以通過使用 signals,設(shè)計(jì)好的API(中間件,extensions,pipelines)來定制實(shí)現(xiàn)您的功能。
  • 內(nèi)置的中間件及擴(kuò)展為下列功能提供了支持:
    • cookies and session 處理
    • HTTP 壓縮
    • HTTP 認(rèn)證
    • HTTP 緩存
    • user-agent 模擬
    • robots.txt
    • 爬取深度限制
    • 其他
  • 針對非英語語系中不標(biāo)準(zhǔn)或者錯誤的編碼聲明, 提供了自動檢測以及健壯的編碼支持。
  • 支持根據(jù)模板生成爬蟲。在加速爬蟲創(chuàng)建的同時,保持在大型項(xiàng)目中的代碼更為一致。詳細(xì)內(nèi)容請參閱 genspider 命令。
  • 針對多爬蟲下性能評估、失敗檢測,提供了可擴(kuò)展的狀態(tài)收集工具
  • 提供交互式 shell 終端,為您測試 XPath 表達(dá)式,編寫和調(diào)試爬蟲提供了極大的方便
  • 提供 System service,簡化在生產(chǎn)環(huán)境的部署及運(yùn)行
  • 內(nèi)置 Telnet 終端 ,通過在 Scrapy 進(jìn)程中鉤入 Python 終端,使您可以查看并且調(diào)試爬蟲
  • Logging 為您在爬取過程中捕捉錯誤提供了方便
  • 支持 Sitemaps 爬取
  • 具有緩存的 DNS 解析器

接下來

下一步當(dāng)然是 下載 Scrapy 了, 您可以閱讀Scrapy 入門教程并加入社區(qū)。感謝您的支持!