Scrapy爬蟲(chóng)入門教程四 Spider(爬蟲(chóng))

Python版本管理:pyenv和pyenv-virtualenv
Scrapy爬蟲(chóng)入門教程一 安裝和基本使用
Scrapy爬蟲(chóng)入門教程二 官方提供Demo
Scrapy爬蟲(chóng)入門教程三 命令行工具介紹和示例
Scrapy爬蟲(chóng)入門教程四 Spider(爬蟲(chóng))
Scrapy爬蟲(chóng)入門教程五 Selectors(選擇器)
Scrapy爬蟲(chóng)入門教程六 Items(項(xiàng)目)
Scrapy爬蟲(chóng)入門教程七 Item Loaders(項(xiàng)目加載器)
Scrapy爬蟲(chóng)入門教程八 交互式 shell 方便調(diào)試
Scrapy爬蟲(chóng)入門教程九 Item Pipeline(項(xiàng)目管道)
Scrapy爬蟲(chóng)入門教程十 Feed exports(導(dǎo)出文件)
Scrapy爬蟲(chóng)入門教程十一 Request和Response(請(qǐng)求和響應(yīng))
Scrapy爬蟲(chóng)入門教程十二 Link Extractors(鏈接提取器)

[toc]

開(kāi)發(fā)環(huán)境:
Python 3.6.0 版本 (當(dāng)前最新)
Scrapy 1.3.2 版本 (當(dāng)前最新)

Spider

爬蟲(chóng)是定義如何抓取某個(gè)網(wǎng)站(或一組網(wǎng)站)的類,包括如何執(zhí)行抓取(即關(guān)注鏈接)以及如何從其網(wǎng)頁(yè)中提取結(jié)構(gòu)化數(shù)據(jù)(即抓取項(xiàng)目)。換句話說(shuō),Spider是您定義用于為特定網(wǎng)站(或在某些情況下,一組網(wǎng)站)抓取和解析網(wǎng)頁(yè)的自定義行為的位置。

對(duì)于爬蟲(chóng),循環(huán)經(jīng)歷這樣的事情:

  1. 您首先生成用于抓取第一個(gè)URL的初始請(qǐng)求,然后指定要使用從這些請(qǐng)求下載的響應(yīng)調(diào)用的回調(diào)函數(shù)。

    第一個(gè)執(zhí)行的請(qǐng)求通過(guò)調(diào)用 start_requests()(默認(rèn)情況下)Request為在start_urls和中指定的URL生成的parse方法獲取, 并且該方法作為請(qǐng)求的回調(diào)函數(shù)。

  2. 在回調(diào)函數(shù)中,您將解析響應(yīng)(網(wǎng)頁(yè)),并返回帶有提取的數(shù)據(jù),Item對(duì)象, Request對(duì)象或這些對(duì)象的可迭代的對(duì)象。這些請(qǐng)求還將包含回調(diào)(可能是相同的),然后由Scrapy下載,然后由指定的回調(diào)處理它們的響應(yīng)。

  3. 在回調(diào)函數(shù)中,您通常使用選擇器來(lái)解析頁(yè)面內(nèi)容 (但您也可以使用BeautifulSoup,lxml或您喜歡的任何機(jī)制),并使用解析的數(shù)據(jù)生成項(xiàng)目。

  4. 最后,從爬蟲(chóng)返回的項(xiàng)目通常將持久存儲(chǔ)到數(shù)據(jù)庫(kù)(在某些項(xiàng)目管道中)或使用Feed導(dǎo)出寫入文件。

即使這個(gè)循環(huán)(或多或少)適用于任何種類的爬蟲(chóng),有不同種類的默認(rèn)爬蟲(chóng)捆綁到Scrapy中用于不同的目的。我們將在這里談?wù)撨@些類型。

class scrapy.spiders.Spider

這是最簡(jiǎn)單的爬蟲(chóng),每個(gè)其他爬蟲(chóng)必須繼承的爬蟲(chóng)(包括與Scrapy捆綁在一起的爬蟲(chóng),以及你自己寫的爬蟲(chóng))。它不提供任何特殊功能。它只是提供了一個(gè)默認(rèn)start_requests()實(shí)現(xiàn),它從start_urlsspider屬性發(fā)送請(qǐng)求,并parse 為每個(gè)結(jié)果響應(yīng)調(diào)用spider的方法。

name
定義此爬蟲(chóng)名稱的字符串。爬蟲(chóng)名稱是爬蟲(chóng)如何由Scrapy定位(和實(shí)例化),因此它必須是唯一的。但是,沒(méi)有什么能阻止你實(shí)例化同一個(gè)爬蟲(chóng)的多個(gè)實(shí)例。這是最重要的爬蟲(chóng)屬性,它是必需的。

如果爬蟲(chóng)抓取單個(gè)域名,通常的做法是在域后面命名爬蟲(chóng)。因此,例如,抓取的爬蟲(chóng)mywebsite.com通常會(huì)被調(diào)用 mywebsite。

注意
在Python 2中,這必須是ASCII。

allowed_domains
允許此爬蟲(chóng)抓取的域的字符串的可選列表,指定一個(gè)列表可以抓取,其它就不會(huì)抓取了。

start_urls
當(dāng)沒(méi)有指定特定網(wǎng)址時(shí),爬蟲(chóng)將開(kāi)始抓取的網(wǎng)址列表。

custom_settings
運(yùn)行此爬蟲(chóng)時(shí)將從項(xiàng)目寬配置覆蓋的設(shè)置字典。它必須定義為類屬性,因?yàn)樵O(shè)置在實(shí)例化之前更新。

有關(guān)可用內(nèi)置設(shè)置的列表,請(qǐng)參閱: 內(nèi)置設(shè)置參考

crawler
此屬性from_crawler()在初始化類后由類方法設(shè)置,并鏈接Crawler到此爬蟲(chóng)實(shí)例綁定到的對(duì)象。

Crawlers在項(xiàng)目中封裝了很多組件,用于單個(gè)條目訪問(wèn)(例如擴(kuò)展,中間件,信號(hào)管理器等)。有關(guān)詳情,請(qǐng)參閱抓取工具API

settings
運(yùn)行此爬蟲(chóng)的配置。這是一個(gè) Settings實(shí)例,有關(guān)此主題的詳細(xì)介紹,請(qǐng)參閱設(shè)置主題

logger
用Spider創(chuàng)建的Python記錄器name。您可以使用它通過(guò)它發(fā)送日志消息,如記錄爬蟲(chóng)程序中所述

from_crawler(crawler,* args,** kwargs )
是Scrapy用來(lái)創(chuàng)建爬蟲(chóng)的類方法。

您可能不需要直接覆蓋這一點(diǎn),因?yàn)槟J(rèn)實(shí)現(xiàn)充當(dāng)方法的代理,__init__()使用給定的參數(shù)args和命名參數(shù)kwargs調(diào)用它。

盡管如此,此方法 在新實(shí)例中設(shè)置crawler和settings屬性,以便以后可以在爬蟲(chóng)程序中訪問(wèn)它們。

  • 參數(shù):
  • crawler(Crawlerinstance) - 爬蟲(chóng)將綁定到的爬蟲(chóng)
  • args(list) - 傳遞給init()方法的參數(shù)
  • kwargs(dict) - 傳遞給init()方法的關(guān)鍵字參數(shù)

start_requests()
此方法必須返回一個(gè)可迭代的第一個(gè)請(qǐng)求來(lái)抓取這個(gè)爬蟲(chóng)。

有了start_requests(),就不寫了start_urls,寫了也沒(méi)有用。

默認(rèn)實(shí)現(xiàn)是:start_urls,但是可以復(fù)寫的方法start_requests。
例如,如果您需要通過(guò)使用POST請(qǐng)求登錄來(lái)啟動(dòng),您可以:

class MySpider(scrapy.Spider):
    name = 'myspider'

    def start_requests(self):
        return [scrapy.FormRequest("http://www.example.com/login",
                                   formdata={'user': 'john', 'pass': 'secret'},
                                   callback=self.logged_in)]

    def logged_in(self, response):
        # here you would extract links to follow and return Requests for
        # each of them, with another callback
        pass

make_requests_from_url(url)
一種接收URL并返回Request 對(duì)象(或Request對(duì)象列表)進(jìn)行抓取的方法。此方法用于在方法中構(gòu)造初始請(qǐng)求 start_requests(),并且通常用于將URL轉(zhuǎn)換為請(qǐng)求。

除非重寫,此方法返回具有方法的Requests parse() 作為它們的回調(diào)函數(shù),并啟用dont_filter參數(shù)(Request有關(guān)更多信息,請(qǐng)參閱類)。

parse(response)
這是Scrapy用于處理下載的響應(yīng)的默認(rèn)回調(diào),當(dāng)它們的請(qǐng)求沒(méi)有指定回調(diào)時(shí)。

該parse方法負(fù)責(zé)處理響應(yīng)并返回所抓取的數(shù)據(jù)或更多的URL。其他請(qǐng)求回調(diào)具有與Spider類相同的要求。

此方法以及任何其他請(qǐng)求回調(diào)必須返回一個(gè)可迭代的Request和dicts或Item對(duì)象。

  • 參數(shù):
  • response(Response) - 解析的響應(yīng)

log(message[, level, component])
包裝器通過(guò)爬蟲(chóng)發(fā)送日志消息logger,保持向后兼容性。有關(guān)詳細(xì)信息,請(qǐng)參閱 從Spider記錄。

closed(reason)
當(dāng)爬蟲(chóng)關(guān)閉時(shí)召喚。此方法為spider_closed信號(hào)的signals.connect()提供了一個(gè)快捷方式。

讓我們看一個(gè)例子:

import scrapy


class MySpider(scrapy.Spider):
    name = 'example.com'
    allowed_domains = ['example.com']
    start_urls = [
        'http://www.example.com/1.html',
        'http://www.example.com/2.html',
        'http://www.example.com/3.html',
    ]

    def parse(self, response):
        self.logger.info('A response from %s just arrived!', response.url)

從單個(gè)回調(diào)中返回多個(gè)請(qǐng)求和項(xiàng):

import scrapy

class MySpider(scrapy.Spider):
    name = 'example.com'
    allowed_domains = ['example.com']
    start_urls = [
        'http://www.example.com/1.html',
        'http://www.example.com/2.html',
        'http://www.example.com/3.html',
    ]

    def parse(self, response):
        for h3 in response.xpath('//h3').extract():
            yield {"title": h3}

        for url in response.xpath('//a/@href').extract():
            yield scrapy.Request(url, callback=self.parse)

你可以直接使用start_requests(),而不是start_urls; 項(xiàng)目可以更加方便獲取數(shù)據(jù):

import scrapy
from myproject.items import MyItem

class MySpider(scrapy.Spider):
    name = 'example.com'
    allowed_domains = ['example.com']

    def start_requests(self):
        yield scrapy.Request('http://www.example.com/1.html', self.parse)
        yield scrapy.Request('http://www.example.com/2.html', self.parse)
        yield scrapy.Request('http://www.example.com/3.html', self.parse)

    def parse(self, response):
        for h3 in response.xpath('//h3').extract():
            yield MyItem(title=h3)

        for url in response.xpath('//a/@href').extract():
            yield scrapy.Request(url, callback=self.parse)

Spider arguments

爬蟲(chóng)可以接收修改其行為的參數(shù)。爬蟲(chóng)參數(shù)的一些常見(jiàn)用法是定義起始URL或?qū)⑴谰W(wǎng)限制到網(wǎng)站的某些部分,但它們可用于配置爬蟲(chóng)的任何功能。

Spider crawl參數(shù)使用該-a選項(xiàng)通過(guò)命令 傳遞。例如:

scrapy crawl myspider -a category=electronics

爬蟲(chóng)可以在他們的init方法中訪問(wèn)參數(shù):

import scrapy

class MySpider(scrapy.Spider):
    name = 'myspider'

    def __init__(self, category=None, *args, **kwargs):
        super(MySpider, self).__init__(*args, **kwargs)
        self.start_urls = ['http://www.example.com/categories/%s' % category]
        # ...

默認(rèn)的init方法將獲取任何爬蟲(chóng)參數(shù),并將它們作為屬性復(fù)制到爬蟲(chóng)。上面的例子也可以寫成如下:

import scrapy

class MySpider(scrapy.Spider):
    name = 'myspider'

    def start_requests(self):
        yield scrapy.Request('http://www.example.com/categories/%s' % self.category)

請(qǐng)記住,spider參數(shù)只是字符串。爬蟲(chóng)不會(huì)自己做任何解析。如果要從命令行設(shè)置start_urls屬性,則必須將它自己解析為列表,使用像 ast.literal_eval 或json.loads之類的屬性 ,然后將其設(shè)置為屬性。否則,你會(huì)導(dǎo)致迭代一個(gè)start_urls字符串(一個(gè)非常常見(jiàn)的python陷阱),導(dǎo)致每個(gè)字符被看作一個(gè)單獨(dú)的url。

有效的用例是設(shè)置使用的http驗(yàn)證憑據(jù)HttpAuthMiddleware 或用戶代理使用的用戶代理UserAgentMiddleware:
scrapy crawl myspider -a http_user=myuser -a http_pass=mypassword -a user_agent=mybot

Spider參數(shù)也可以通過(guò)Scrapyd schedule.jsonAPI 傳遞。請(qǐng)參閱Scrapyd文檔



通用爬蟲(chóng)

Scrapy附帶一些有用的通用爬蟲(chóng),你可以使用它來(lái)子類化你的爬蟲(chóng)。他們的目的是為一些常見(jiàn)的抓取案例提供方便的功能,例如根據(jù)某些規(guī)則查看網(wǎng)站上的所有鏈接,從站點(diǎn)地圖抓取或解析XML / CSV Feed。

對(duì)于在以下爬蟲(chóng)中使用的示例,我們假設(shè)您有一個(gè)TestItemmyproject.items模塊中聲明的項(xiàng)目:

import scrapy

class TestItem(scrapy.Item):
    id = scrapy.Field()
    name = scrapy.Field()
    description = scrapy.Field()

抓取爬蟲(chóng)

類 scrapy.spiders.CrawlSpider
這是最常用的爬行常規(guī)網(wǎng)站的爬蟲(chóng),因?yàn)樗ㄟ^(guò)定義一組規(guī)則為下列鏈接提供了一種方便的機(jī)制。它可能不是最適合您的特定網(wǎng)站或項(xiàng)目,但它是足夠通用的幾種情況,所以你可以從它開(kāi)始,根據(jù)需要覆蓋更多的自定義功能,或只是實(shí)現(xiàn)自己的爬蟲(chóng)。

除了從Spider繼承的屬性(你必須指定),這個(gè)類支持一個(gè)新的屬性:

rules
它是一個(gè)(或多個(gè))Rule對(duì)象的列表。每個(gè)都Rule定義了抓取網(wǎng)站的某種行為。規(guī)則對(duì)象如下所述。如果多個(gè)規(guī)則匹配相同的鏈接,則將根據(jù)它們?cè)诖藢傩灾卸x的順序使用第一個(gè)。

這個(gè)爬蟲(chóng)還暴露了可覆蓋的方法:

parse_start_url(response)
對(duì)于start_urls響應(yīng)調(diào)用此方法。它允許解析初始響應(yīng),并且必須返回Item對(duì)象,Request對(duì)象或包含任何對(duì)象的迭代器。

抓取規(guī)則

class scrapy.spiders.Rule(link_extractor,callback = None,cb_kwargs = None,follow = None,process_links = None,process_request = None )
link_extractor是一個(gè)鏈接提取程序?qū)ο螅x如何從每個(gè)爬網(wǎng)頁(yè)面提取鏈接。

callback是一個(gè)可調(diào)用的或字符串(在這種情況下,將使用具有該名稱的爬蟲(chóng)對(duì)象的方法),以便為使用指定的link_extractor提取的每個(gè)鏈接調(diào)用。這個(gè)回調(diào)接收一個(gè)響應(yīng)作為其第一個(gè)參數(shù),并且必須返回一個(gè)包含Item和 Request對(duì)象(或它們的任何子類)的列表。

警告
當(dāng)編寫爬網(wǎng)爬蟲(chóng)規(guī)則時(shí),避免使用parse作為回調(diào),因?yàn)?code>CrawlSpider使用parse方法本身來(lái)實(shí)現(xiàn)其邏輯。所以如果你重寫的parse方法,爬行爬蟲(chóng)將不再工作。

cb_kwargs 是包含要傳遞給回調(diào)函數(shù)的關(guān)鍵字參數(shù)的dict。

follow是一個(gè)布爾值,它指定是否應(yīng)該從使用此規(guī)則提取的每個(gè)響應(yīng)中跟蹤鏈接。如果callbackNone follow默認(rèn)為True,否則默認(rèn)為False

process_links是一個(gè)可調(diào)用的或一個(gè)字符串(在這種情況下,將使用具有該名稱的爬蟲(chóng)對(duì)象的方法),將使用指定從每個(gè)響應(yīng)提取的每個(gè)鏈接列表調(diào)用該方法link_extractor。這主要用于過(guò)濾目的。

process_request 是一個(gè)可調(diào)用的或一個(gè)字符串(在這種情況下,將使用具有該名稱的爬蟲(chóng)對(duì)象的方法),它將被此規(guī)則提取的每個(gè)請(qǐng)求調(diào)用,并且必須返回一個(gè)請(qǐng)求或無(wú)(過(guò)濾出請(qǐng)求) 。

抓取爬蟲(chóng)示例

現(xiàn)在讓我們來(lái)看一個(gè)CrawlSpider的例子:

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

class MySpider(CrawlSpider):
    name = 'example.com'
    allowed_domains = ['example.com']
    start_urls = ['http://www.example.com']

    rules = (
        # Extract links matching 'category.php' (but not matching 'subsection.php')
        # and follow links from them (since no callback means follow=True by default).
        Rule(LinkExtractor(allow=('category\.php', ), deny=('subsection\.php', ))),

        # Extract links matching 'item.php' and parse them with the spider's method parse_item
        Rule(LinkExtractor(allow=('item\.php', )), callback='parse_item'),
    )

    def parse_item(self, response):
        self.logger.info('Hi, this is an item page! %s', response.url)
        item = scrapy.Item()
        item['id'] = response.xpath('//td[@id="item_id"]/text()').re(r'ID: (\d+)')
        item['name'] = response.xpath('//td[@id="item_name"]/text()').extract()
        item['description'] = response.xpath('//td[@id="item_description"]/text()').extract()
        return item

這個(gè)爬蟲(chóng)會(huì)開(kāi)始抓取example.com的主頁(yè),收集類別鏈接和項(xiàng)鏈接,用parse_item方法解析后者。對(duì)于每個(gè)項(xiàng)目響應(yīng),將使用XPath從HTML中提取一些數(shù)據(jù),并將Item使用它填充。

XMLFeedSpider

class scrapy.spiders.XMLFeedSpider
XMLFeedSpider設(shè)計(jì)用于通過(guò)以特定節(jié)點(diǎn)名稱迭代XML訂閱源來(lái)解析XML訂閱源。迭代器可以選自:iternodes,xml和html。iternodes為了性能原因,建議使用迭代器,因?yàn)閤ml和迭代器html一次生成整個(gè)DOM為了解析它。但是,html當(dāng)使用壞標(biāo)記解析XML時(shí),使用作為迭代器可能很有用。

要設(shè)置迭代器和標(biāo)記名稱,必須定義以下類屬性:

  • iterator
    定義要使用的迭代器的字符串。它可以是:

  • 'iternodes' - 基于正則表達(dá)式的快速迭代器

  • 'html'- 使用的迭代器Selector。請(qǐng)記住,這使用DOM解析,并且必須加載所有DOM在內(nèi)存中,這可能是一個(gè)大飼料的問(wèn)題

  • 'xml'- 使用的迭代器Selector。請(qǐng)記住,這使用DOM解析,并且必須加載所有DOM在內(nèi)存中,這可能是一個(gè)大飼料的問(wèn)題
    它默認(rèn)為:'iternodes'

itertag
一個(gè)具有要迭代的節(jié)點(diǎn)(或元素)的名稱的字符串。示??例:
itertag = 'product'

namespaces
定義該文檔中將使用此爬蟲(chóng)處理的命名空間的元組列表。在 與將用于自動(dòng)注冊(cè)使用的命名空間 的方法。(prefix, uri)prefixuriregister_namespace()

然后,您可以在屬性中指定具有命名空間的itertag 節(jié)點(diǎn)。

例:

class YourSpider(XMLFeedSpider):

    namespaces = [('n', 'http://www.sitemaps.org/schemas/sitemap/0.9')]
    itertag = 'n:url'
    # ...

除了這些新的屬性,這個(gè)爬蟲(chóng)也有以下可重寫的方法:

adapt_response(response)
一種在爬蟲(chóng)開(kāi)始解析響應(yīng)之前,在響應(yīng)從爬蟲(chóng)中間件到達(dá)時(shí)立即接收的方法。它可以用于在解析之前修改響應(yīng)主體。此方法接收響應(yīng)并返回響應(yīng)(它可以是相同的或另一個(gè))。

parse_node(response, selector)
對(duì)于與提供的標(biāo)記名稱(itertag)匹配的節(jié)點(diǎn),將調(diào)用此方法。接收Selector每個(gè)節(jié)點(diǎn)的響應(yīng)和 。覆蓋此方法是必需的。否則,你的爬蟲(chóng)將不工作。此方法必須返回一個(gè)Item對(duì)象,一個(gè) Request對(duì)象或包含任何對(duì)象的迭代器。

process_results(response, results)
對(duì)于由爬蟲(chóng)返回的每個(gè)結(jié)果(Items or Requests),將調(diào)用此方法,并且它將在將結(jié)果返回到框架核心之前執(zhí)行所需的任何最后處理,例如設(shè)置項(xiàng)目ID。它接收結(jié)果列表和產(chǎn)生那些結(jié)果的響應(yīng)。它必須返回結(jié)果列表(Items or Requests)。

XMLFeedSpider示例

這些爬蟲(chóng)很容易使用,讓我們看一個(gè)例子:

from scrapy.spiders import XMLFeedSpider
from myproject.items import TestItem

class MySpider(XMLFeedSpider):
    name = 'example.com'
    allowed_domains = ['example.com']
    start_urls = ['http://www.example.com/feed.xml']
    iterator = 'iternodes'  # This is actually unnecessary, since it's the default value
    itertag = 'item'

    def parse_node(self, response, node):
        self.logger.info('Hi, this is a <%s> node!: %s', self.itertag, ''.join(node.extract()))

        item = TestItem()
        item['id'] = node.xpath('@id').extract()
        item['name'] = node.xpath('name').extract()
        item['description'] = node.xpath('description').extract()
        return item

基本上我們做的是創(chuàng)建一個(gè)爬蟲(chóng),從給定的下載一個(gè)start_urls,然后遍歷每個(gè)item標(biāo)簽,打印出來(lái),并存儲(chǔ)一些隨機(jī)數(shù)據(jù)Item。

CSVFeedSpider

class scrapy.spiders.CSVF
這個(gè)爬蟲(chóng)非常類似于XMLFeedSpider,除了它迭代行,而不是節(jié)點(diǎn)。在每次迭代中調(diào)用的方法是parse_row()。

delimiter
CSV文件中每個(gè)字段的帶分隔符的字符串默認(rèn)為','(逗號(hào))。

quotechar
CSV文件中每個(gè)字段的包含字符的字符串默認(rèn)為'"'(引號(hào))。

headers
文件CSV Feed中包含的行的列表,用于從中提取字段。

parse_row(response, row)
使用CSV文件的每個(gè)提供(或檢測(cè)到)標(biāo)頭的鍵接收響應(yīng)和dict(表示每行)。這個(gè)爬蟲(chóng)還給予機(jī)會(huì)重寫adapt_response和process_results方法的前和后處理的目的。

CSVFeedSpider示例

讓我們看一個(gè)類似于前一個(gè)例子,但使用 CSVFeedSpider:

from scrapy.spiders import CSVFeedSpider
from myproject.items import TestItem

class MySpider(CSVFeedSpider):
    name = 'example.com'
    allowed_domains = ['example.com']
    start_urls = ['http://www.example.com/feed.csv']
    delimiter = ';'
    quotechar = "'"
    headers = ['id', 'name', 'description']

    def parse_row(self, response, row):
        self.logger.info('Hi, this is a row!: %r', row)

        item = TestItem()
        item['id'] = row['id']
        item['name'] = row['name']
        item['description'] = row['description']
        return item

SitemapSpider

class scrapy.spiders.SitemapSpider
SitemapSpider允許您通過(guò)使用Sitemaps發(fā)現(xiàn)網(wǎng)址來(lái)抓取網(wǎng)站

它支持嵌套Sitemap和從robots.txt發(fā)現(xiàn)Sitemap網(wǎng)址 。

sitemap_urls
指向您要抓取的網(wǎng)址的網(wǎng)站的網(wǎng)址列表。

您還可以指向robots.txt,它會(huì)解析為從中提取Sitemap網(wǎng)址。

sitemap_rules
元組列表其中:(regex, callback)

  • regex是與從Sitemap中提取的網(wǎng)址相匹配的正則表達(dá)式。 regex可以是一個(gè)str或一個(gè)編譯的正則表達(dá)式對(duì)象。
  • callback是用于處理與正則表達(dá)式匹配的url的回調(diào)。callback可以是字符串(指示蜘蛛方法的名稱)或可調(diào)用的。

例如:
sitemap_rules = [('/product/', 'parse_product')]

規(guī)則按順序應(yīng)用,只有匹配的第一個(gè)將被使用。
如果省略此屬性,則會(huì)在parse回調(diào)中處理在站點(diǎn)地圖中找到的所有網(wǎng)址。

sitemap_follow
應(yīng)遵循的網(wǎng)站地圖的正則表達(dá)式列表。這只適用于使用指向其他Sitemap文件的Sitemap索引文件的網(wǎng)站。

默認(rèn)情況下,將跟蹤所有網(wǎng)站地圖。

sitemap_alternate_links
指定是否url應(yīng)遵循一個(gè)備用鏈接。這些是在同一個(gè)url塊中傳遞的另一種語(yǔ)言的同一網(wǎng)站的鏈接。

例如:

<url>
    <loc>http://example.com/</loc>
    <xhtml:link rel="alternate" hreflang="de" />
</url>

使用sitemap_alternate_linksset,這將檢索兩個(gè)URL。隨著 sitemap_alternate_links禁用,只有http://example.com/將進(jìn)行檢索。

默認(rèn)為sitemap_alternate_links禁用。

SitemapSpider示例

最簡(jiǎn)單的示例:使用parse回調(diào)處理通過(guò)站點(diǎn)地圖發(fā)現(xiàn)的所有網(wǎng)址 :

from scrapy.spiders import SitemapSpider

class MySpider(SitemapSpider):
    sitemap_urls = ['http://www.example.com/sitemap.xml']

    def parse(self, response):
        pass # ... scrape item here ...

使用某個(gè)回調(diào)處理一些網(wǎng)址,并使用不同的回調(diào)處理其他網(wǎng)址:

from scrapy.spiders import SitemapSpider

class MySpider(SitemapSpider):
    sitemap_urls = ['http://www.example.com/sitemap.xml']
    sitemap_rules = [
        ('/product/', 'parse_product'),
        ('/category/', 'parse_category'),
    ]

    def parse_product(self, response):
        pass # ... scrape product ...

    def parse_category(self, response):
        pass # ... scrape category ...

關(guān)注robots.txt文件中定義的sitemaps,并且只跟蹤其網(wǎng)址包含/sitemap_shop以下內(nèi)容的Sitemap :

from scrapy.spiders import SitemapSpider

class MySpider(SitemapSpider):
    sitemap_urls = ['http://www.example.com/robots.txt']
    sitemap_rules = [
        ('/shop/', 'parse_shop'),
    ]
    sitemap_follow = ['/sitemap_shops']

    def parse_shop(self, response):
        pass # ... scrape shop here ...

將SitemapSpider與其他來(lái)源網(wǎng)址結(jié)合使用:

from scrapy.spiders import SitemapSpider

class MySpider(SitemapSpider):
    sitemap_urls = ['http://www.example.com/robots.txt']
    sitemap_rules = [
        ('/shop/', 'parse_shop'),
    ]

    other_urls = ['http://www.example.com/about']

    def start_requests(self):
        requests = list(super(MySpider, self).start_requests())
        requests += [scrapy.Request(x, self.parse_other) for x in self.other_urls]
        return requests

    def parse_shop(self, response):
        pass # ... scrape shop here ...

    def parse_other(self, response):
        pass # ... scrape other here ...
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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