1. Scrapy中的链接提取器
在爬取网站数据时,我们通常需要爬取页面中的链接,Scrapy提供了一个链接提取器,方便我们从页面中提取需要的链接。
1.1 LinkExtractor介绍
LinkExtractor是Scrapy中的一个类,用于从页面中提取链接。该类的使用方法如下:
from scrapy.linkextractors import LinkExtractor
extractor = LinkExtractor()
links = extractor.extract_links(response)
在上面的代码中,我们首先从Scrapy中导入LinkExtractor类。接着,我们创建了一个LinkExtractor对象,并调用extract_links方法,该方法传入一个response参数,返回一个包含页面中所有链接的列表。
1.2 LinkExtractor常用参数
LinkExtractor有许多可选参数,以下介绍一些比较常用的参数。
allow:一个正则表达式,用于匹配需要提取的链接。例如,allow=r'category\.php'将只提取包含"category.php"的链接。
deny:一个正则表达式,用于匹配不需要提取的链接。例如,deny=r'\?sort='将不会提取包含"sort="参数的链接。
allow_domains:一个列表,用于限制提取链接的域名。例如,allow_domain=['example.com']将只提取example.com域下的链接。
deny_domains:一个列表,用于排除某些域名的链接。例如,deny_domains=['example.com']将排除example.com域下的链接。
restrict_xpaths:一个XPath表达式,用于指定需要提取链接的HTML元素。例如,restrict_xpaths='//div[@class="content"]'将只提取包含"content"类名的div下的链接。
2. Scrapy中的链接去重工具
在爬取网站数据时,我们可能会遇到重复的链接,为了避免浪费资源和时间,Scrapy提供了一个链接去重工具。
2.1 Link deduplicator
Link deduplicator是Scrapy中的一个重复链接去重工具,用于防止重复抓取相同的链接。该工具的使用方法如下:
from scrapy.dupefilters import RFPDupeFilter
dupefilter = RFPDupeFilter()
request1 = scrapy.Request(url='http://www.example.com')
request2 = scrapy.Request(url='http://www.example.com')
dupefilter.request_seen(request1) # 返回False,request1未被处理过
dupefilter.request_seen(request2) # 返回True,request2已经被处理过
在上面的代码中,我们首先从Scrapy中导入RFPDupeFilter类。接着,我们创建了一个RFPDupeFilter对象,并分别传入两个请求request1和request2。调用request_seen方法,当request1被处理后返回False,当request2被处理时返回True,表示request2已经被处理过。
2.2 RFPDupeFilter常用参数
RFPDupeFilter有一些可选参数,以下介绍一些比较常用的参数。
dupefilter_key:一个函数,可用于自定义生成URL的key。默认值为'{}.{}'.format(request.dont_filter, url)。
debug:一个布尔值,用于控制是否打印日志。默认值为False。
log_count:一个整数,用于控制日志输出的内容。默认值为1。
3. Scrapy中的链接提取器和去重工具示例
下面我们将使用Scrapy中的链接提取器和去重工具来爬取一个网站的数据。
首先,我们需要创建一个Scrapy项目:
scrapy startproject myproject
cd myproject
scrapy genspider example example.com
在我们的spider中,我们需要导入LinkExtractor和RFPDupeFilter类,并设置rules和dupefilter参数:
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.dupefilters import RFPDupeFilter
class ExampleSpider(CrawlSpider):
name = 'example'
allowed_domains = ['example.com']
start_urls = ['http://www.example.com']
rules = (
Rule(LinkExtractor(allow=('category\.php',)), callback='parse_category', follow=True),
)
custom_settings = {
'DUPEFILTER_CLASS': "scrapy.dupefilters.RFPDupeFilter",
}
def parse_category(self, response):
# do something
pass
在上面的代码中,我们导入了LinkExtractor和RFPDupeFilter类,并在spider中设置了rules和custom_settings参数。其中,rules参数指定了需要提取的链接,并通过callback参数指定了解析函数。custom_settings参数指定了使用RFPDupeFilter作为去重工具。
接着,我们编写解析函数parse_category,用于处理从链接提取器中提取的链接:
def parse_category(self, response):
links = LinkExtractor(allow=('product\.php',)).extract_links(response)
for link in links:
yield scrapy.Request(link.url, callback=self.parse_product)
def parse_product(self, response):
# do something
pass
在上面的代码中,我们使用LinkExtractor从response中提取所有包含"product.php"的链接,并通过yield生成对应的Request对象,通过callback参数指定了解析函数parse_product。
最后,我们需要运行爬虫程序:
scrapy crawl example
通过上面的步骤,我们就可以爬取example.com网站的数据,并通过链接提取器和去重工具来优化爬取过程。