如何在 Scrapy 中使用自定义的 Spider 去重策略进行 URL 去重和处理?
要实现自定义的 Spider 去重策略,需要继承 Scrapy 的 dupefilters.BaseDupeFilter
类,并实现 request_seen(request)
和 open()
方法。其中 request_seen(request)
方法用于判断请求是否已经处理过,open()
方法用于打开去重数据存储。
首先需要创建一个新的去重策略类,在类中实现 request_seen(request)
和 open()
方法。下面是一个简单的例子:
from scrapy.dupefilters import BaseDupeFilter from scrapy.utils.request import request_fingerprint class MyDupeFilter(BaseDupeFilter): def __init__(self, path=None): self.urls_seen = set() BaseDupeFilter.__init__(self, path) def request_seen(self, request): url = request.url.split('?')[0] finger = request_fingerprint(request) if url in self.urls_seen: return True self.urls_seen.add(url) self.file.write(finger + '\n') return False def open(self): self.file = open(self.file_path, 'a+') self.urls_seen = set(line.strip() for line in self.file)
在该例子中,request_seen(request)
方法使用了一个 set
类型的变量 urls_seen
来存储已经处理过的请求的 url,通过检查 url 是否已经存在来判断当前请求是否已经被处理过。如果当前请求没有被处理过,则将其 fingerprint(可以理解为请求的唯一标识)写入文件,并且返回 False
表示该请求需要被处理。open()
方法会打开一个文件并读取其中已经存在的 fingerprint,存储在 urls_seen
变量中,以便后续查询。
下一步是将自定义的去重策略类与 Spider 建立关联。要实现这一点,需要在 Spider 中添加一个 DUPEFILTER_CLASS
属性,该属性值为自定义的去重策略类。例如,以下是使用自定义去重策略类的演示:
import scrapy class MySpider(scrapy.Spider): name = "myspider" start_urls = [ "http://pidancode.com/", "http://pidancode.com/2018-01-01", "http://pidancode.com/2018-01-02", "http://pidancode.com/2018-01-03", "http://pidancode.com/2018-01-04", "http://pidancode.com/2018-01-05", "http://pidancode.com/2018-01-06", "http://pidancode.com/2018-01-07" ] custom_settings = { 'DUPEFILTER_CLASS': 'myproject.dupefilter.MyDupeFilter', } def parse(self, response): pass
这个例子中,我们定义了一个名为 MySpider
的 Spider,并指定了 DUPEFILTER_CLASS
属性为我们定义的去重策略类 myproject.dupefilter.MyDupeFilter
。此后我们在该 Spider 中的请求就会使用自定义去重策略进行去重。
最后,需要注意的是,在使用自定义去重策略时,与默认的去重策略不一样的是,对于同一个 url 不同的查询参数,也会被认为是不同的,因此需要对 URL 进行处理,只保留前面的部分。例如,在上述去重类中,我们将 URL 的查询参数部分去掉了,只保留了 URL 的前半部分。
相关文章