我正在为使用CrawlSpider scrapy的网站编写一个爬虫 .
Scrapy提供了一个内置的重复请求过滤器,可根据URL过滤重复的请求 . 此外,我可以使用CrawlSpider的规则成员过滤请求 .
我想要做的是过滤以下请求:
http:://www.abc.com/p/xyz.html?id=1234&refer=5678
如果我已经访问过
http:://www.abc.com/p/xyz.html?id=1234&refer=4567
注意:refer是一个不影响我得到的响应的参数,所以我不在乎该参数的值是否发生变化 .
现在,如果我有一个累积所有ID的集合,我可以在我的回调函数parse_item(这是我的回调函数)中忽略它来实现此功能 .
但这意味着当我不需要时,我至少仍然会 grab 那个页面 .
那么我告诉scrapy它不应该基于url发送特定请求的方式是什么?
4 回答
您可以编写自定义中间件以进行重复删除,并将其添加到设置中
然后,您需要在settings.py中设置正确的DUPFILTER_CLASS
它应该在那之后工作
在ytomar的带领下,我编写了这个过滤器,它基于通过检查内存集已经看到的URL进行过滤 . 我是一个Python菜鸟让我知道如果我搞砸了什么,但似乎工作正常:
正如ytomar所提到的,请务必将
DUPEFILTER_CLASS
常量添加到settings.py
:https://github.com/scrapinghub/scrapylib/blob/master/scrapylib/deltafetch.py
这个文件可以帮到你 . 此文件从url创建唯一delta获取密钥的数据库,用户在scrapy中传递.Reqeust(meta = {'deltafetch_key':uniqe_url_key}) . 这样,您就可以避免过去曾访问过的重复请求 .
使用deltafetch.py的示例mongodb实现
例如 . id = 345 scrapy.Request(url,meta = {deltafetch_key:345},callback = parse)
这是我的自定义过滤器基于scrapy 0.24.6 .
在此过滤器中,它仅关注URL中的id . 例如
http://www.example.com/products/cat1/1000.html?p=1
http://www.example.com/products/cat2/1000.html?p=2
被视为相同的网址 . 但
http://www.example.com/products/cat2/all.html
将不会 .