LinkExtractor的使用非常简单,通过一个例子进行讲解,使用LinkExtractor替代Selector完成BooksSpider提取链接的任务,代码如下:

 

对上述代码解释如下:

● 导入LinkExtractor,它位于scrapy.linkextractors模块。

● 创建一个LinkExtractor对象,使用一个或多个构造器参数描述提取规则,这里传递给restrict_css参数一个CSS选择器表达式。它描述出下一页链接所在的区域(在li.next下)。

● 调用LinkExtractor对象的extract_links方法传入一个Response对象,该方法依据创建对象时所描述的提取规则,在Response对象所包含的页面中提取链接,最终返回一个列表,其中的每一个元素都是一个Link对象,即提取到的一个链接。

● 由于页面中的下一页链接只有一个,因此用links[0]获取Link对象,Link对象的url属性便是链接页面的绝对url地址(无须再调用response.urljoin方法),用其构造Request对象并提交。

通过上面的例子,相信大家已经了解了使用LinkExtractor对象提取页面中链接的流程。

6.2 描述提取规则

接下来,我们来学习使用LinkExtractor的构造器参数描述提取规则。

为了在讲解过程中举例,首先制造一个实验环境,创建两个包含多个链接的HTML页面:

使用以上两个HTML文本构造两个Response对象:

 

现在有了实验环境,先说明一种特例情况,LinkExtractor构造器的所有参数都有默认值,如果构造对象时不传递任何参数(使用默认值),就提取页面中所有链接。以下代码将提取页面example1.html中的所有链接:

 

下面依次介绍LinkExtractor构造器的各个参数:

● allow

接收一个正则表达式或一个正则表达式列表,提取绝对url与正则表达式匹配的链接,如果该参数为空(默认),就提取全部链接。

示例 提取页面example1.html中路径以/intro开始的链接:

 

● deny

接收一个正则表达式或一个正则表达式列表,与allow相反,排除绝对url与正则表达式匹配的链接。

示例 提取页面example1.html中所有站外链接(即排除站内链接):

 

● allow_domains

接收一个域名或一个域名列表,提取到指定域的链接。

示例 提取页面example1.html中所有到github.com和stackoverflow.com这两个域的链接:

 

● deny_domains

接收一个域名或一个域名列表,与allow_domains相反,排除到指定域的链接。

示例 提取页面example1.html中除了到github.com域以外的链接:

● restrict_xpaths

接收一个XPath表达式或一个XPath表达式列表,提取XPath表达式选中区域下的链接。

示例 提取页面example1.html中<div id="top">元素下的链接:

 

● restrict_css

接收一个CSS选择器或一个CSS选择器列表,提取CSS选择器选中区域下的链接。

示例 提取页面example1.html中<div id="bottom">元素下的链接:

● tags

接收一个标签(字符串)或一个标签列表,提取指定标签内的链接,默认为['a', 'area']。

● attrs

接收一个属性(字符串)或一个属性列表,提取指定属性内的链接,默认为['href']。

示例 提取页面example2.html中引用JavaScript文件的链接:

 

● process_value

接收一个形如func(value)的回调函数。如果传递了该参数,LinkExtractor将调用该回调函数对提取的每一个链接(如a的href)进行处理,回调函数正常情况下应返回一个字符串(处理结果),想要抛弃所处理的链接时,返回None。

示例 在页面example2.html中,某些a的href属性是一段JavaScript代码,代码中包含了链接页面的实际url地址,此时应对链接进行处理,提取页面example2.html中所有实际链接:

 

到此,我们介绍完了LinkExtractor构造器的各个参数,实际应用时可以同时使用一个或多个参数描述提取规则,这里不再举例。