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.php
和example.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
Python爬虫之Scrapy框架系列(12)——实战ZH小说的爬取来深入学习CrawlSpider