2.5 Link Extractors (链接提取器)


文档摘要

2.5 Link Extractors (链接提取器) 2.5 Link Extractors (链接提取器) 在 Scrapy 爬虫中,链接提取器 (Link Extractors) 扮演着至关重要的角色。它们负责从 HTML 或 XML 文档中提取链接,以便爬虫能够沿着这些链接继续抓取其他页面。如果没有链接提取器,爬虫就只能抓取起始页面,而无法深入到网站的其他部分。 2.5.1 链接提取器的作用 链接提取器的主要作用是: 发现新的 URL: 从已抓取的页面中找到新的 URL,这些 URL 指向网站的其他页面或外部资源。 控制爬取范围: 通过设置规则,可以限制爬虫只抓取特定类型的链接,例如只抓取属于特定域名的链接或符合特定模式的链接。

在 Scrapy 爬虫中,链接提取器 (Link Extractors) 扮演着至关重要的角色。它们负责从 HTML 或 XML 文档中提取链接,以便爬虫能够沿着这些链接继续抓取其他页面。如果没有链接提取器,爬虫就只能抓取起始页面,而无法深入到网站的其他部分。

2.5.1 链接提取器的作用

链接提取器的主要作用是:

  • 发现新的 URL: 从已抓取的页面中找到新的 URL,这些 URL 指向网站的其他页面或外部资源。

  • 控制爬取范围: 通过设置规则,可以限制爬虫只抓取特定类型的链接,例如只抓取属于特定域名的链接或符合特定模式的链接。

  • 简化爬虫代码: 将链接提取的逻辑从爬虫代码中分离出来,使爬虫代码更加简洁和易于维护。

Scrapy 提供了 scrapy.linkextractors 模块,其中包含了一些常用的链接提取器。最常用的链接提取器是 LxmlLinkExtractor,它基于 lxml 库,具有高性能和灵活性。

from scrapy.linkextractors import LxmlLinkExtractor

2.5.3 LxmlLinkExtractor 的常用参数

LxmlLinkExtractor 提供了丰富的参数,可以根据不同的需求进行配置。以下是一些常用的参数:

  • allow (str or iterable): 一个正则表达式或一个正则表达式列表,用于匹配允许提取的 URL。只有匹配该正则表达式的 URL 才会被提取。

  • deny (str or iterable): 一个正则表达式或一个正则表达式列表,用于匹配禁止提取的 URL。匹配该正则表达式的 URL 将不会被提取。

  • allow_domains (str or iterable): 一个域名或一个域名列表,用于指定允许提取链接的域名。

  • deny_domains (str or iterable): 一个域名或一个域名列表,用于指定禁止提取链接的域名。

  • restrict_xpaths (str or iterable): 一个 XPath 表达式或一个 XPath 表达式列表,用于指定在哪些 XPath 区域内提取链接。

  • restrict_css (str or iterable): 一个 CSS 选择器或一个 CSS 选择器列表,用于指定在哪些 CSS 选择器区域内提取链接。

  • tags (str or iterable): 一个标签名或一个标签名列表,用于指定要提取链接的标签。默认为 ('a', 'area')

  • attrs (str or iterable): 一个属性名或一个属性名列表,用于指定要提取链接的属性。默认为 ('href',)

  • canonicalize (bool): 是否对提取的 URL 进行规范化处理。默认为 True

2.5.4 代码实践

下面通过一个简单的例子来演示如何使用 LxmlLinkExtractor

示例:提取博客文章列表页面的文章链接

假设我们要从一个博客的文章列表页面提取所有文章的链接。该页面的 HTML 结构如下:

<div class="article-list"> <article> <h2><a href="/article/1">文章1</a></h2> <p>文章1的摘要...</p> </article> <article> <h2><a href="/article/2">文章2</a></h2> <p>文章2的摘要...</p> </article> <article> <h2><a href="/article/3">文章3</a></h2> <p>文章3的摘要...</p> </article> </div>

我们可以使用以下代码来提取文章链接:

import scrapy from scrapy.linkextractors import LxmlLinkExtractor class BlogSpider(scrapy.Spider): name = "blog_spider" start_urls = ["http://example.com/blog"] # 替换成你的博客列表页URL def parse(self, response): # 创建一个 LxmlLinkExtractor 实例,restrict_xpaths 指定提取链接的区域 le = LxmlLinkExtractor(restrict_xpaths="//div[@class='article-list']/article/h2") # 使用 extract_links 方法提取链接 links = le.extract_links(response) # 遍历提取到的链接 for link in links: print(f"提取到的链接:{link.url}") # 可以对提取到的链接进行进一步处理,例如发起新的请求 # yield scrapy.Request(link.url, callback=self.parse_article) def parse_article(self, response): # 这里编写解析文章页面的代码 pass

代码解释:

  1. 导入模块: 导入 scrapyLxmlLinkExtractor

  2. 定义 Spider 类: 创建一个名为 BlogSpider 的 Spider 类,并设置 namestart_urls

  3. parse 方法: 这是爬虫的主要解析方法。

    • 创建 LxmlLinkExtractor 实例,并使用 restrict_xpaths 参数指定只在 class="article-list"div 元素下的 article 元素下的 h2 元素中提取链接。

    • 调用 extract_links 方法,传入 response 对象,该方法会返回一个 Link 对象列表。

    • 遍历 Link 对象列表,打印提取到的 URL。

    • (可选) 可以使用 yield scrapy.Request 发起新的请求,抓取文章页面。

  4. parse_article 方法: (可选) 用于解析文章页面的方法。

运行爬虫:

将以上代码保存为 blog_spider.py,然后在命令行中运行以下命令:

scrapy crawl blog_spider

爬虫将会抓取 start_urls 中指定的页面,并提取所有符合条件的链接,并在控制台中打印出来。

2.5.5 使用 allowdeny 参数

allowdeny 参数可以用来更精确地控制链接提取。

示例:只提取包含 "article" 的链接,排除包含 "category" 的链接

import scrapy from scrapy.linkextractors import LxmlLinkExtractor class BlogSpider(scrapy.Spider): name = "blog_spider" start_urls = ["http://example.com/blog"] # 替换成你的博客列表页URL def parse(self, response): # 创建一个 LxmlLinkExtractor 实例,使用 allow 和 deny 参数 le = LxmlLinkExtractor(allow="article", deny="category") # 使用 extract_links 方法提取链接 links = le.extract_links(response) # 遍历提取到的链接 for link in links: print(f"提取到的链接:{link.url}") # 可以对提取到的链接进行进一步处理,例如发起新的请求 # yield scrapy.Request(link.url, callback=self.parse_article) def parse_article(self, response): # 这里编写解析文章页面的代码 pass

在这个例子中,allow="article" 表示只提取 URL 中包含 "article" 的链接,deny="category" 表示排除 URL 中包含 "category" 的链接。

2.5.6 使用 restrict_css 参数

restrict_css 参数可以使用 CSS 选择器来指定提取链接的区域。

示例:提取 class="article-list"div 元素下的所有链接

import scrapy from scrapy.linkextractors import LxmlLinkExtractor class BlogSpider(scrapy.Spider): name = "blog_spider" start_urls = ["http://example.com/blog"] # 替换成你的博客列表页URL def parse(self, response): # 创建一个 LxmlLinkExtractor 实例,使用 restrict_css 参数 le = LxmlLinkExtractor(restrict_css=".article-list") # 使用 extract_links 方法提取链接 links = le.extract_links(response) # 遍历提取到的链接 for link in links: print(f"提取到的链接:{link.url}") # 可以对提取到的链接进行进一步处理,例如发起新的请求 # yield scrapy.Request(link.url, callback=self.parse_article) def parse_article(self, response): # 这里编写解析文章页面的代码 pass

在这个例子中,restrict_css=".article-list" 表示只在 class="article-list"div 元素下提取链接。

虽然 Scrapy 提供了默认的链接提取器,但在某些情况下,可能需要自定义链接提取器来满足特定的需求。 可以继承 scrapy.linkextractors.LinkExtractor 类并重写其方法来实现自定义的链接提取逻辑。

from scrapy.linkextractors import LinkExtractor from scrapy.link import Link class MyLinkExtractor(LinkExtractor): def __init__(self, *args, **kwargs): super(MyLinkExtractor, self).__init__(*args, **kwargs) def extract_links(self, response): # 自定义链接提取逻辑 links = [] # ... (你的提取逻辑) ... return links

图示解释:

  1. 爬虫接收到 Response 对象。

  2. Response 对象被传递给 LxmlLinkExtractor 实例。

  3. LxmlLinkExtractor 根据配置的规则 (例如 allowdenyrestrict_xpaths 等) 从 Response 中提取链接。

  4. 符合规则的链接被封装成 Link 对象。

  5. 不符合规则的链接被忽略。

  6. LxmlLinkExtractor 返回一个 Link 对象列表。

2.5.9 总结

链接提取器是 Scrapy 爬虫中不可或缺的组件。通过灵活配置链接提取器的参数,可以精确控制爬虫的抓取范围,提高爬虫的效率。 掌握链接提取器的使用方法,可以让你编写出更加强大和高效的 Scrapy 爬虫。


发布者: 作者: 转发
评论区 (0)
U