为什么要自定义过滤规则呢? 首先,我们需要过滤,但是不是说抓一次就不抓了,因为我们的抓取是一段时间抓取一次

自定义策略如下:

首先我试图直接继承RFPDupeFilter

在settings.py同级的目录下新建dupefilter.py文件,按照网上说的方法,写了内容如下

from scrapy.dupefilter import RFPDupeFilter
import hashlib
from scrapy.utils.request import request_fingerprint
from scrapy.dupefilter import BaseDupeFilterclass URLFilter(RFPDupeFilter):def __init(self):RFPDupeFilter.__init__(self)def request_seen(self, request):fp = self.request_fingerprint(request)added = self.server.sadd(self.key, fp)return added == 0

在settings.py中添加

DUPEFILTER_CLASS = 'CrawlBaiduMobile.dupefilter.URLFilter'

但是启动spider会报如下错误:

ValueError: ("Failed to instantiate dupefilter class '%s': %s", 'CrawlBaiduMobile.dupefilter.URLFilter', TypeError("__init__() got an unexpected keyword argument 'debug'",))

或者报

ValueError: ("Failed to instantiate dupefilter class '%s': %s", 'CrawlBaiduMobile.dupefilter.URLFilter', TypeError("__init__() got an unexpected keyword argument 'key'",))

含义其实也很明显, 调用RFPDupeFilter的构造方法时出错了,可能是我的版本比较新吧。

于是我找到了RFPDupeFilter的源码,写了一个基本和它一致的, 但是过滤策略有些不同

from scrapy_redis.dupefilter import RFPDupeFilter
from scrapy_redis.connection import get_redis_from_settings
from scrapy.dupefilters import BaseDupeFilter
from scrapy.utils.request import request_fingerprint
from scrapy_redis import defaults
import hashlibclass URLFilter(BaseDupeFilter):def __init__(self, server, key, debug=False):self.server = serverself.key = keyself.debug = debugself.logdupes = Trueself.timeout = 60*60*24*10    #设置过期时间10天,10天内重复的url不重复抓取@classmethoddef from_settings(cls, settings):server = get_redis_from_settings(settings)key = defaults.DUPEFILTER_KEY % {'timestamp': int(time.time())}debug = settings.getbool('DUPEFILTER_DEBUG')return cls(server, key=key, debug=debug)@classmethoddef from_crawler(cls, crawler):return cls.from_settings(crawler.settings)def request_seen(self, request):key = self.request_fingerprint(request)if self.server.get(key):return Trueelse:self.server.set(key, 1, self.timeout) def request_fingerprint(self, request):return hashlib.md5(request.url).hexdigest()

我依然用了redis存储缓存key,但是用的字符串,没有再用有序集合,因为我们的策略是一段时间内不重复抓取,所以需要给抓取过的key设置一个缓存时间

此外,缓存key的生成方式也做了修订,改用了md5算法生成了一个40位的key

在实验过程中发现一个问题,start_urls中的url没有进这个过滤器

首先看下start_urls中的初始url是如何被构造成Request的

def start_requests(self):for url in self.start_urls:yield self.make_requests_from_url(url)def make_requests_from_url(self, url):return Request(url, dont_filter=True)

在start_requests中会将start_urls里面的url(当然也可以是redis中的),通过make_requests_from_url方法构造成Request对象

但是传参dont_filter=True,也就是不经过过滤器的,所以默认情况下,初始start_urls中的url不会经过上面配置的过滤器

可以在spider中覆写这个方法, 设置dont_filter=False:

class CrawlBaiduMobile(RedisCrawlSpider):#some other codedef make_requests_from_url(self, url):return Request(url, dont_filter=False)

此外,图片下载的Request也没有进这个过滤器

配置页面中的图片下载:

class CrawlImagePipeline(ImagesPipeline):def get_media_requests(self, item, info):if isinstance(item, CrawlImageItem):for image_url in item['image_urls']:self.default_headers['referer'] = image_urlyield Request(image_url, headers=self.default_headers, dont_filter=False)

这里也用了yield Request,  但是这个Request不会进入到上面配置的过滤器中, 即使给了dont_filter=False,当然更具体是什么原因,我没有深究了, 因为我们的系统对于抓取图片有不同的过滤规则,的确也不需要经过这个过滤器

图片下载应该是有一套自己的排重策略,就是用过期时间,可以在settings.py中配置,

IMAGES_EXPIRES = 90   #90天内重复的图片不会再下载, 如果服务重启了,之前保存的下载过的图片会重新下载

scrapy中自定义过滤规则以及start_urls不进过滤器的问题相关推荐

  1. Nintendo Switch AdGuard 自定义过滤规则

    为了不被BAN机 利用AdGuard Home的自定义过滤规则 屏蔽任天堂所有域名DNS解析.具体规则如下: ||nintendo.*^ ||nintendoswitch.*^ 建议在PC上进行检测后 ...

  2. 傲游浏览器 页面广告过滤 自定义 过滤规则 及使用方法 不定时更新

    使用方法: 1.打开傲游浏览器,打开以下列表中需要过滤广告的域名 2.单击傲游浏览器右下角广告猎手,点击编辑过滤规则 3.将以下列表的规则粘贴到右侧输入框中 4.点击完成,页面会自动刷新,完成后页面广 ...

  3. adblock plus 增加自定义过滤规则,禁止弹出广告网页和隐藏广告块

    电影下载网站,经常会有嵌入广告,比如点击页面任何地方,都会弹出其它的彩票/游戏网站. 或者在页面中有很多个广告块,游戏视频,彩票网站,购物广告. 即便开启了adblock plus,仍然能看到一些广告 ...

  4. 数据库中自定义排序规则,Mysql中自定义字段排序规则,Oracle中自定义字段排序规则,decode函数的用法,field函数的用法

    数据库中自定义排序 场景:有一张banner表,表中有一个status字段,有0, 1, 2三个状态位,我想要 1,0,2的自定义排序(这里是重点),然后再进行之上对sequence字段进行二次排序( ...

  5. 教你三种Model(AR)中自定义验证规则的方法

    2019独角兽企业重金招聘Python工程师标准>>> 各位Yii2兄弟都知道Model的rules里面可以使用自己定义的验证规则,我们今天就把自定义规则做一个总结,进行一次彻底的知 ...

  6. shiro学习(20): 自定义过滤规则

    工具idea 先看看数据库 shiro_role_permission 数据 shiro_user shiro_user_role 数据 目录结构 在pom.xml里面添加 <?xml vers ...

  7. abp过滤规则android,ABP的数据过滤器(Data Filters)

    我们在数据库开发中,一般会运用软删除 (soft delete)模式 ,即不直接从数据库删除数据 ,而是标记这笔数据为已删除.因此 ,如果实体被软删除了,那么它就应该不会在应用程序中被检索到.要达到这 ...

  8. wireshark抓包后查看数据报时的过滤规则/过滤语法及举例说明

    wireshark抓包后查看数据报时的过滤规则/过滤语法及举例说明过滤器的区别捕捉过滤器(CaptureFilters):用于决定将什么样的信息记录在捕捉结果中.需要在开始捕捉前设置.显示过滤器(Di ...

  9. iptables及其过滤规则

    1. iptables是Linux内核的一个模块,用以管理对网络设备(网卡)的访问,如路由过滤.端口转发.NAT等,root用户可以通过iptables配置操作系统的路由表.在当前的主流Linux发布 ...

最新文章

  1. 用C语言编写小学四则运算程序,用C语言编写生成小学四则运算程序
  2. linux 网桥的管理和搭建
  3. dos命令 cd命令使用说明[图文说明]
  4. Spring异常重试框架Spring Retry
  5. linux下文件系统创建
  6. Nginx的配置使用,启动、重启、关闭,以及路径配置
  7. oracle和mysql数据实时同步_Canal 实现 Mysql数据库实时数据同步
  8. 使用Bind配置DNS Load Balancing
  9. 妙用chrome插件,实现U校园自动填答案
  10. Windows错误“ 0xc0000005”
  11. 宝付浅谈物流无人机发展历程
  12. 2020.7-8月份暑假培训总结
  13. nisp一级练习题及答案
  14. 自动化设备远程监控系统软件
  15. CSMA/CD与CSMA/CA区别
  16. Python 函数式编程Map、Reduce
  17. 前端学习笔记之流程控制语句和数组(六)
  18. XY的模式识别学习笔记-最小平方误差准则分类 MSE
  19. 如何建设网上订货商城系统 订货系统建设流程分享
  20. 通过HWND取得pid以及HANDLE

热门文章

  1. Oracle定时调用存储过程
  2. Vivado常见问题集锦
  3. 01.备份crm源码
  4. oracle ebs应用产品安全性-交叉验证规则
  5. Oracle收购后的Mysql目标市场
  6. 追MM与23种设计模式
  7. javascript 将页面上的Table导出保存为Excel (无格式)
  8. 【Java】什么是多态?多态的实现机制是什么?
  9. Spark中如何管理Spark Streaming消费Kafka的偏移量
  10. 03-09 toast 控件识别