文章目录
使用 LinkExtractor 提取链接
1. 提取链接的方法
在爬取一个网站时,想要爬取的数据通常分布在多个页面中,每个页面包含一部分数据以及到其他页面的链接,提取页面中数据的方法大家已经掌握,提取链接有使用 Selector 和使用 LinkExtractor 两种方法。
(1)使用Selector
因为链接也是页面中的数据,所以可以使用与提取数据相同的方法进行提取,在提取少量链接或提取规则比较简单时,使用 Selector 就足够了。例如我们在项目 toscrapy
中编写爬虫 books.py 的数据解析函数 parse()
时,就是用了 Selector 提取了下一个页面的链接,代码如下:
class BooksSpider(scrapy.Spider):
name = 'books'
allowed_domains = ['books.toscrape.com']
start_urls = ['http://books.toscrape.com/']
def parse(self, response):
......
# 提取链接
next_url = response.css('ul.pager li.next a::attr(href)').extract_first()
if next_url:
next_url = response.urljoin(next_url)
yield scrapy.Request(next_url, callback=self.parse)
第一种方法我们早已掌握,下面学习如何使用 LinkExtractor 提取链接。
(2)使用LinkExtractor
Scrapy 提供了一个专门用于提取链接的类 LinkExtractor,在提取大量链接或提取规则比较复杂时,使用 LinkExtractor 更加方便。
LinkExtractor 的使用非常简单,我们通过将上述代码中的 Selector 替换成 LinkExtractor 进行讲解,代码如下:
from scrapy.linkextractors import LinkExtractor
class BooksSpider(scrapy.Spider):
name = 'books'
allowed_domains = ['books.toscrape.com']
start_urls = ['http://books.toscrape.com/']
def parse(self, response):
...
# 提取链接
le = LinkExtractor(restrict_css='ul.pager li.next')
links = le.extract_links(response)
if links:
next_url = links[0].url
yield scrapy.Request(next_url, callback=self.parse)
代码解析如下:
- Step 1:创建一个 LinkExtractor 对象,使用一个或多个构造器参数描述提取规则。这里传递给
restrict_css
参数一个 CSS 选择器表达式。它描述出下一页链接所在的区域(在 li.next 下)。 - Step 2:调用 LinkExtractor 对象的
extract_links
方法传入一个 Response 对象,该方法依据创建对象时所描述的提取规则, 在 Response 对象所包含的页面中提取链接,最终返回一个列表,其中的每一个元素都是一个 Link 对象,即提取到的一个链接。 - Step 3:由于页面中的下一页链接只有一个,因此用 links[0] 获取 LinkExtractor 对象,LinkExtractor 对象的 url 属性便是链接页面的绝对 url 地址(无须再调用
response.urljoin
方法),用其构造 Request 对象并提交。
2. LinkExtractor 提取链接的规则
接下来,我们来学习使用 LinkExtractor 的构造器参数描述提取链接的规则。
首先我们创建两个包含多个链接的HTML页面,作为 LinkExtractor 提取链接的示例网页:
<!-- example1.html -->
<html>
<body>
<div id="top">
<p>下面是一些站内链接</p>
<a class="internal" href="/intro/install.html">Installation guide</a>
<a class