2.10 CrawlSpider 和 Rule


文档摘要

2.10 CrawlSpider 和 Rule Scrapy CrawlSpider 与 Rule 详解 Scrapy 提供了多种 Spider 基类,其中 是一个非常强大的 Spider,特别适用于需要从网站上抓取多个页面,并遵循特定链接模式的情况。 依赖于 对象来定义抓取规则,从而实现自动化的页面发现和抓取。 CrawlSpider 简介 继承自 类,并添加了一些新的功能,使其能够根据预定义的规则自动发现和抓取链接。与需要手动解析每个页面并提取链接的 不同, 可以根据 自动完成这些任务。 CrawlSpider 的主要特点: 规则驱动: 通过 对象定义链接提取和页面处理规则。 自动化链接发现: 自动从匹配规则的页面中提取链接。 可配置性: 可以灵活配置链接提取规则和回调函数。

2.10 CrawlSpider 和 Rule

Scrapy CrawlSpider 与 Rule 详解

Scrapy 提供了多种 Spider 基类,其中 CrawlSpider 是一个非常强大的 Spider,特别适用于需要从网站上抓取多个页面,并遵循特定链接模式的情况。CrawlSpider 依赖于 Rule 对象来定义抓取规则,从而实现自动化的页面发现和抓取。

1. CrawlSpider 简介

CrawlSpider 继承自 Spider 类,并添加了一些新的功能,使其能够根据预定义的规则自动发现和抓取链接。与需要手动解析每个页面并提取链接的 Spider 不同,CrawlSpider 可以根据 Rule 自动完成这些任务。

CrawlSpider 的主要特点:

  • 规则驱动: 通过 Rule 对象定义链接提取和页面处理规则。

  • 自动化链接发现: 自动从匹配规则的页面中提取链接。

  • 可配置性: 可以灵活配置链接提取规则和回调函数。

  • 避免重复抓取: 默认情况下,会过滤掉重复的链接。

2. Rule 对象详解

Rule 对象定义了如何从页面中提取链接以及如何处理提取到的链接。Rule 对象包含以下几个重要的参数:

  • link_extractor (Link Extractor 对象): 用于从页面中提取链接的 Link Extractor 对象。

  • callback (callable): 当 Link Extractor 提取到链接时,用于处理 response 的回调函数。

  • cb_kwargs (dict): 传递给回调函数的关键字参数。

  • follow (boolean): 指定是否跟随提取到的链接。如果为 True,则会递归地抓取提取到的链接;如果为 False,则只抓取当前页面。

  • process_links (callable): 用于过滤链接的回调函数。

  • process_request (callable): 用于处理请求的回调函数。

Link Extractor 负责从页面中提取链接。Scrapy 提供了多种内置的 Link Extractor,最常用的是 LxmlLinkExtractor

LxmlLinkExtractor 的常用参数:

  • allow (regex or string): 允许提取的链接的 URL 必须匹配的正则表达式或字符串。

  • deny (regex or string): 禁止提取的链接的 URL 必须匹配的正则表达式或字符串。

  • allow_domains (str or list): 允许提取的链接的域名。

  • deny_domains (str or list): 禁止提取的链接的域名。

  • restrict_xpaths (str or list): 限制链接提取的 XPath 表达式。

  • restrict_css (str or list): 限制链接提取的 CSS 选择器。

  • tags (str or list): 提取链接的标签。默认为 ('a', 'area')

  • attrs (str or list): 提取链接的属性。默认为 ('href',)

4. CrawlSpider 代码实践

下面是一个使用 CrawlSpiderRule 抓取博客文章的示例:

import scrapy from scrapy.spiders import CrawlSpider, Rule from scrapy.linkextractors import LxmlLinkExtractor class BlogSpider(CrawlSpider): name = 'blogspider' allowed_domains = ['example.com'] start_urls = ['http://example.com/blog'] rules = ( Rule(LxmlLinkExtractor(allow=r'/blog/\d+/\d+/\d+/'), callback='parse_item', follow=True), Rule(LxmlLinkExtractor(allow=r'/blog/page/\d+/'), follow=True), # 抓取分页链接 ) def parse_item(self, response): item = {} item['title'] = response.css('h1.entry-title::text').get() item['content'] = response.css('div.entry-content::text').getall() item['url'] = response.url return item

代码解释:

  1. name: Spider 的名称,用于在 Scrapy 中标识 Spider。

  2. allowed_domains: 允许抓取的域名列表。

  3. start_urls: Spider 启动时要抓取的 URL 列表。

  4. rules: 一个包含 Rule 对象的元组,定义了抓取规则。

    • 第一个 Rule 使用 LxmlLinkExtractor 提取 URL 匹配 r'/blog/\d+/\d+/\d+/' (例如 /blog/2023/10/26/) 的链接,并使用 parse_item 方法处理 response。follow=True 表示会继续抓取这些链接指向的页面。

    • 第二个 Rule 使用 LxmlLinkExtractor 提取 URL 匹配 r'/blog/page/\d+/' (例如 /blog/page/2/) 的链接,follow=True 表示会继续抓取这些分页链接指向的页面。 这个规则没有指定 callback,所以只是提取链接并继续抓取,不会调用任何解析函数。

  5. parse_item: 回调函数,用于处理抓取到的页面。在这个例子中,它提取文章的标题、内容和 URL,并将它们存储在一个字典中。

5. Rule 的优先级和顺序

CrawlSpider 会按照 rules 列表中 Rule 对象的顺序依次应用规则。如果一个 URL 匹配多个 Rule,则会按照规则的顺序依次执行。

可以通过在 Rule 对象中设置 priority 参数来调整规则的优先级。priority 值越大,优先级越高。

6. 避免重复抓取

CrawlSpider 默认使用 RFPDupeFilter 中间件来过滤重复的请求。这意味着如果一个 URL 已经被抓取过,CrawlSpider 就不会再次抓取它。

可以通过设置 dont_filter=True 来禁用重复请求过滤。但是,通常情况下不建议这样做,因为它可能导致无限循环和大量的重复抓取。

7. 使用 process_linksprocess_request

process_linksprocess_requestRule 对象中两个非常有用的参数,可以用于更精细地控制链接提取和请求处理。

  • process_links: 接受一个回调函数,该函数接收一个链接列表作为参数,并返回一个过滤后的链接列表。这可以用于在链接被添加到抓取队列之前对其进行过滤或修改。

    def filter_links(links): filtered_links = [] for link in links: if 'example.com' in link.url: filtered_links.append(link) return filtered_links rules = ( Rule(LxmlLinkExtractor(allow=r'/blog/\d+/\d+/\d+/'), callback='parse_item', follow=True, process_links=filter_links), )
  • process_request: 接受一个回调函数,该函数接收一个 Request 对象作为参数,并返回一个 Request 对象。这可以用于在请求被发送之前对其进行修改,例如添加 headers 或 cookies。

    def add_header(request): request.headers['My-Header'] = 'My-Value' return request rules = ( Rule(LxmlLinkExtractor(allow=r'/blog/\d+/\d+/\d+/'), callback='parse_item', follow=True, process_request=add_header), )

8. CrawlSpider 的优势和局限性

优势:

  • 简化开发: 自动化的链接发现和抓取,减少了手动解析和提取链接的工作量。

  • 高效抓取: 可以高效地抓取大型网站,并遵循特定的链接模式。

  • 可扩展性: 可以通过自定义 Rule 对象来扩展抓取规则。

局限性:

  • 规则复杂性: 当抓取规则非常复杂时,Rule 对象的配置可能会变得困难。

  • 动态内容: 对于大量使用 JavaScript 动态加载内容的网站,CrawlSpider 可能无法有效地抓取链接。

9. Mermaid 图表

下面是一个 Mermaid 图表,展示了 CrawlSpider 的工作流程:

图表解释:

  1. Start URLs 是 Spider 启动时要抓取的 URL 列表。

  2. CrawlSpider 根据 Rule 对象定义的规则,从页面中提取链接。

  3. Link Extractor 负责从页面中提取链接。

  4. 如果链接匹配 Ruleallow 规则,则会调用 callback 函数处理 response。

  5. callback 函数提取数据并将其传递给 Item Pipeline

  6. Item Pipeline 处理数据并将其存储到数据库或文件中。

  7. CrawlSpider 会继续抓取提取到的链接,直到所有链接都被抓取完毕。

10. 总结

CrawlSpider 是 Scrapy 中一个非常强大的 Spider,特别适用于需要从网站上抓取多个页面,并遵循特定链接模式的情况。通过 Rule 对象,可以灵活地配置链接提取规则和回调函数,从而实现自动化的页面发现和抓取。掌握 CrawlSpiderRule 的使用方法,可以大大提高 Scrapy 爬虫的开发效率。

在实际应用中,需要根据网站的结构和抓取需求,灵活地配置 Rule 对象的参数,例如 allowdenyrestrict_xpathsrestrict_css 等。同时,还需要注意避免重复抓取和处理动态内容等问题。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U