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

使用 Firebug 進(jìn)行爬取

注解

本教程所使用的樣例站 Google Directory 已經(jīng)被 Google 關(guān)閉了。不過(guò)教程中的概念任然適用。 如果您打算使用一個(gè)新的網(wǎng)站來(lái)更新本教程,您的貢獻(xiàn)是再歡迎不過(guò)了。 詳細(xì)信息請(qǐng)參考 Contributing to Scrapy

介紹

本文檔介紹了如何適用 Firebug(一個(gè) Firefox 的插件)來(lái)使得爬取更為簡(jiǎn)單,有趣。更多有意思的 Firefox 插件請(qǐng)參考對(duì)爬取有幫助的實(shí)用 Firefox 插件。使用 Firefox 插件檢查頁(yè)面需要有些注意事項(xiàng):在瀏覽器中檢查 DOM 的注意事項(xiàng)

在本樣例中將展現(xiàn)如何使用 FirebugGoogle Directory 來(lái)爬取數(shù)據(jù)。Google Directory 包含了入門(mén)教程里所使用的 Open Directory Project 中一樣的數(shù)據(jù),不過(guò)有著不同的結(jié)構(gòu)。

Firebug 提供了非常實(shí)用的檢查元素功能。該功能允許您將鼠標(biāo)懸浮在不同的頁(yè)面元素上, 顯示相應(yīng)元素的 HTML 代碼。否則,您只能十分痛苦的在 HTML 的 body 中手動(dòng)搜索標(biāo)簽。

在下列截圖中,您將看到 檢查元素 的執(zhí)行效果。

http://wiki.jikexueyuan.com/project/scrapy/images/1.png" alt="" />

首先我們能看到目錄根據(jù)種類(lèi)進(jìn)行分類(lèi)的同時(shí),還劃分了子類(lèi)。

不過(guò),看起來(lái)子類(lèi)還有更多的子類(lèi),而不僅僅是頁(yè)面顯示的這些,所以我們接著查找:

http://wiki.jikexueyuan.com/project/scrapy/images/2.png" alt="" />

正如路徑的概念那樣,子類(lèi)包含了其他子類(lèi)的鏈接,同時(shí)也鏈接到實(shí)際的網(wǎng)站中。

獲取到跟進(jìn)(follow)的鏈接

查看路徑的 URL,我們可以看到 URL 的通用模式(pattern):

http://directory.google.com/Category/Subcategory/Another_Subcategory

了解到這個(gè)消息,我們可以構(gòu)建一個(gè)跟進(jìn)的鏈接的正則表達(dá)式:

directory\.google\.com/[A-Z][a-zA-Z_/]+$

因此,根據(jù)這個(gè)表達(dá)式,我們創(chuàng)建第一個(gè)爬取規(guī)則:

Rule(LinkExtractor(allow='directory.google.com/[A-Z][a-zA-Z_/]+$', ),
    'parse_category',
    follow=True,
),

Rule 對(duì)象指導(dǎo)基于 CrawlSpider 的 spider 如何跟進(jìn)目錄鏈接。 parse_category 是 spider 的方法,用于從頁(yè)面中處理也提取數(shù)據(jù)。

spider 的代碼如下:

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

class GoogleDirectorySpider(CrawlSpider):
    name = 'directory.google.com'
    allowed_domains = ['directory.google.com']
    start_urls = ['http://directory.google.com/']

    rules = (
        Rule(LinkExtractor(allow='directory\.google\.com/[A-Z][a-zA-Z_/]+$'),
            'parse_category', follow=True,
        ),
    )

    def parse_category(self, response):
        # write the category page data extraction code here
        pass

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

現(xiàn)在我們來(lái)編寫(xiě)提取數(shù)據(jù)的代碼。

在 Firebug 的幫助下,我們將查看一些包含網(wǎng)站鏈接的網(wǎng)頁(yè)(以 http://directory.google.com/Top/Arts/Awards/為例),找到使用 Selectors 提取鏈接的方法。我們也將使用 Scrapy shell 來(lái)測(cè)試得到的 XPath 表達(dá)式,確保表達(dá)式工作符合預(yù)期。

http://wiki.jikexueyuan.com/project/scrapy/images/3.png" alt="" />

正如您所看到的那樣,頁(yè)面的標(biāo)記并不是十分明顯: 元素并不包含 id,class 或任何可以區(qū)分的屬性。所以我們將使用等級(jí)槽(rank bar)作為指示點(diǎn)來(lái)選擇提取的數(shù)據(jù),創(chuàng)建 XPath。

使用 Firebug,我們可以看到每個(gè)鏈接都在 td 標(biāo)簽中。該標(biāo)簽存在于同時(shí)(在另一個(gè) td)包含鏈接的等級(jí)槽(ranking bar)的 tr 中。

所以我們選擇等級(jí)槽(ranking bar),接著找到其父節(jié)點(diǎn)(tr),最后是(包含我們要爬取數(shù)據(jù)的)鏈接的 td 。

對(duì)應(yīng)的 XPath:

//td[descendant::a[contains(@href, "#pagerank")]]/following-sibling::td//a

使用 Scrapy 終端來(lái)測(cè)試這些復(fù)雜的 XPath 表達(dá)式,確保其工作符合預(yù)期。

簡(jiǎn)單來(lái)說(shuō),該表達(dá)式會(huì)查找等級(jí)槽的 td 元素,接著選擇所有 td 元素,該元素?fù)碛凶訉O a 元素,且 a 元素的屬性 href 包含字符串 #pagerank。

當(dāng)然,這不是唯一的 XPath,也許也不是選擇數(shù)據(jù)的最簡(jiǎn)單的那個(gè)。 其他的方法也可能是,例如,選擇灰色的鏈接的 font 標(biāo)簽。

最終,我們編寫(xiě) parse_category()方法:

def parse_category(self, response):

    # The path to website links in directory page
    links = response.xpath('//td[descendant::a[contains(@href, "#pagerank")]]/following-sibling::td/font')

    for link in links:
        item = DirectoryItem()
        item['name'] = link.xpath('a/text()').extract()
        item['url'] = link.xpath('a/@href').extract()
        item['description'] = link.xpath('font[2]/text()').extract()
        yield item

注意,您可能會(huì)遇到有些在 Firebug 找到,但是在原始 HTML 中找不到的元素, 例如典型的 <tbody>元素, 或者 Firebug 檢查活動(dòng) DOM(live DOM)所看到的元素,但元素由 javascript 動(dòng)態(tài)生成,并不在 HTML 源碼中。 (原文語(yǔ)句亂了,上面為意譯- -: or tags which Therefer in page HTML sources may on Firebug inspects the live DOM )。