Scrapy - 了解 CrawlSpider 和 LinkExtractor

Posted

技术标签:

【中文标题】Scrapy - 了解 CrawlSpider 和 LinkExtractor【英文标题】:Scrapy - Understanding CrawlSpider and LinkExtractor 【发布时间】:2017-11-15 14:46:27 【问题描述】:

所以我尝试使用 CrawlSpider 并理解Scrapy Docs 中的以下示例:

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

然后给出的描述是:

这个蜘蛛会开始爬取 example.com 的主页,收集类别链接和项目链接,并使用 parse_item 方法解析后者。对于每个项目响应,将使用 XPath 从 html 中提取一些数据,并用它填充一个项目。

我知道对于第二条规则,它从item.php 中提取链接,然后使用parse_item 方法提取信息。但是,第一条规则的目的究竟是什么?它只是说它“收集”了链接。这是什么意思?如果他们不从中提取任何数据,为什么它有用?

【问题讨论】:

【参考方案1】:

CrawlSpider 在抓取论坛搜索帖子时非常有用,或者在搜索产品页面时对在线商店进行分类。

这个想法是,您必须“以某种方式”进入每个类别,搜索与您要提取的产品/项目信息相对应的链接。这些产品链接是该示例的第二条规则中指定的链接(它表示 URL 中包含 item.php 的链接)。

现在蜘蛛应该如何继续访问链接直到找到包含item.php 的链接?这是第一条规则。它说访问包含category.php 但不包含subsection.php 的每个链接,这意味着它不会从这些链接中准确提取任何“项目”,但它定义了蜘蛛查找真实项目的路径。

这就是为什么您会看到它在规则中不包含 callback 方法,因为它不会返回该链接响应供您处理,因为它将被直接跟踪。

【讨论】:

啊,我明白了...所以这个蜘蛛会从example.com/category.php/item.php 之类的链接中提取数据,但不会从example.com/subsection.php/item.php 之类的任何链接中提取数据? 是的,如果你的意思是提取example.com/subsection.php/item.php,它首先需要访问页面example.com/subsection.php。假设您在example.com(主页),并且在该页面内它只有2个链接(在正文内):example.com/category.phpexample.com/subsection.php,当您访问它们时,您可以找到产品网址(item.php )。然后蜘蛛只会提取category.php 中的那些,因为它从未访问过subsection.php 我明白了...谢谢!那么如果有人说还有第三个链接example.com/third.php/item.php 但我有与上面相同的规则,它会解析这些链接吗?只是对行为感到困惑,因为third.php 既不在allow=() 也不在deny=() 中。您是否必须手动拒绝所有可能的额外链接? 如果蜘蛛在category.php 链接中发现third.php/item.php 链接,那么是的,它将被提取。它只说它将访问category.php 链接。它不会访问category.php/subsection.php 链接。请记住,“已访问”链接与“提取”链接不同。 再次,如果在example.com/third.php 中找到该链接(认为这是一个类别),那么不会。现在“如果”以某种方式找到该链接,该链接将被“提取”,因此您可以在parse_item 上处理它。我认为在_requests_to_follow method of CrawlSpider 中解释了整个功能

以上是关于Scrapy - 了解 CrawlSpider 和 LinkExtractor的主要内容,如果未能解决你的问题,请参考以下文章

Python爬虫-Scrapy-CrawlSpider与ItemLoader

scrapy框架之(CrawlSpider)

Python爬虫之Scrapy框架系列(12)——实战ZH小说的爬取来深入学习CrawlSpider

Python爬虫之Scrapy框架系列(12)——实战ZH小说的爬取来深入学习CrawlSpider

scrapy框架之CrawlSpider

Scrapy框架中的CrawlSpider