1. extensions.py文件
  2.  
  3. # -*- coding: utf-8 -*-
  4. # 该扩展会在以下事件时记录一条日志:
  5. # spider被打开
  6. # spider被关闭
  7. # 爬取了特定数量的条目(items)

  8. import logging
  9. from collections import defaultdict
  10. from scrapy import signals
  11. from scrapy.exceptions import NotConfigured
  12. from datetime import datetime
  13.  
  14. logger = logging.getLogger(__name__)
  15.  
  16. class SpiderOpenCloseLogging(object):
  17.  
  18. def __init__(self, item_count):
  19. self.item_count = item_count
  20. self.items_scraped = 0
  21. self.items_dropped = 0
  22. self.stats = defaultdict(int) # 默认是0 正常状态
  23. self.err_stats = defaultdict(int) # 默认是0
  24. print("=="*20, 'Extension object created 扩展对象被创建')
  25.  
  26. @classmethod
  27. def from_crawler(cls, crawler):
  28. # first check if the extension should be enabled and raise
  29.  
  30. # NotConfigured otherwise
  31. # 关键:这里如果是False就直接放弃对象的创建了,在settings中写一个MYEXT_ENABLED,设置为True
  32. if not crawler.settings.getbool('MYEXT_ENABLED'):
  33. raise NotConfigured
  34.  
  35. # get the number of items from settings
  36. # 默认每爬1000条才记录一次log,可以在settings中设置这个MYEXT_ITEMCOUNT数字
  37. item_count = crawler.settings.getint('MYEXT_ITEMCOUNT', 1000)
  38.  
  39. # instantiate the extension object
  40.  
  41. ext = cls(item_count)
  42.  
  43. # connect the extension object to signals
  44. # 把ext.spider_opened这个函数绑定到signal=signals.spider_opened这个信号上,
  45. # 每当一个item对象被yield出来的时候,这个信号就会产生
  46. crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened)
  47.  
  48. crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed)
  49.  
  50. # signals.item_scraped这个是主要的信号,前提是一个item被爬之后,并通过所有的Pipeline没有被drop掉
  51. crawler.signals.connect(ext.item_scraped, signal=signals.item_scraped)
  52.  
  53. # 注册一个item_dropped信号,当item被drop之后这个信号会触发
  54. crawler.signals.connect(ext.item_dropped, signal=signals.item_dropped)
  55.  
  56. # 注册一个ext.response_received
  57. crawler.signals.connect(ext.response_received, signal=signals.response_received)
  58.  
  59. # return the extension object
  60.  
  61. return ext
  62.  
  63. def spider_opened(self, spider):
  64. # spider.log("opened spider %s" % spider.name)
  65. # 可以把spider.log替换成print
  66. print("opened spider %s" % spider.name)
  67.  
  68. def spider_closed(self, spider):
  69. # spider.log("closed spider %s" % spider.name)
  70. # 可以把spider.log替换成print
  71. print("closed spider %s" % spider.name)
  72.  
  73. def item_scraped(self, item, spider):
  74. self.items_scraped += 1
  75. if self.items_scraped % self.item_count == 0:
  76. # spider.log("scraped %d items" % self.items_scraped)
  77. # 可以把spider.log替换成print
  78. print("scraped %d items" % self.items_scraped)
  79.  
  80. def item_dropped(self, item, spider, response, exception):
  81. self.items_dropped += 1
  82. if self.items_dropped % self.item_count == 0:
  83. # spider.log("scraped %d items" % self.items_scraped)
  84. print("dropped %d items" % self.items_dropped)
  85.  
  86. def response_received(self, response, request, spider): # 监控爬虫的健康情况
  87. # 统计当前这一分钟正确状态和错误状态的数量
  88. now = datetime.now().strftime('%Y%m%d%H%M')
  89. self.stats[now] += 1 # 正常状态+!
  90. if response.status in [401, 403, 404, 500, 501, 502]:
  91. self.err_stats[now] += 1 # 错误状态+1
  92. if self.err_stats[now] / float(self.stats[now]) > 0.2: # 占比
  93. # 一般线上部署有warning信息会发邮件,有err信息会发短信
  94. # warning级别比err低,但是比info高
  95. logger.warning(f'received {self.stats[now]} response and {self.err_stats[now]} of them is not 200,{now}')
  1. settings中配置文件
  2.  
  3. # Enable or disable extensions
  4. # See https://docs.scrapy.org/en/latest/topics/extensions.html
  5. MYEXT_ENABLED = True # 使用自定义插件
  6. MYEXT_ITEMCOUNT = 10 # 每爬10条打印一次或者记录一次日志
  7. EXTENSIONS = {
  8. # 'scrapy.extensions.telnet.TelnetConsole': None,
  9. 'qianmu.extensions.SpiderOpenCloseLogging': 1,
  10. }
  1.  

scrapy的扩展件extensions的更多相关文章

  1. XAML实例教程系列 - 标记扩展(Markup Extensions) 六

    XAML实例教程系列 - 标记扩展(Markup Extensions) 分类: Windows 8 Silverlight2012-06-21 13:00 1139人阅读 评论(0) 收藏 举报 扩 ...

  2. nginx+php+扩展件安装实践版

    一.安装各种软件包 yum -y install wget git vim lrzsz unzip zip gcc make gd-devel bzip2 bzip2-devel libcurl li ...

  3. swift学习笔记之-扩展(Extensions)

    //扩展(Extensions) import UIKit /*扩展(Extensions):扩展 就是为一个已有的类.结构体.枚举类型或者协议类型添加新功能.这包括在没有权限获取原始源代码的情况下扩 ...

  4. 16.AutoMapper 之可查询扩展(Queryable Extensions)

    https://www.jianshu.com/p/4b23e94a7825 可查询扩展(Queryable Extensions) 当在像NHibernate或者Entity Framework之类 ...

  5. MySQL索引扩展(Index Extensions)学习总结

    MySQL InnoDB的二级索引(Secondary Index)会自动补齐主键,将主键列追加到二级索引列后面.详细一点来说,InnoDB的二级索引(Secondary Index)除了存储索引列k ...

  6. Welcome-to-Swift-20扩展(Extensions)

    扩展就是向一个已有的类.结构体或枚举类型添加新功能(functionality).这包括在没有权限获取原始源代码的情况下扩展类型的能力(即逆向建模).扩展和 Objective-C 中的分类(cate ...

  7. 类别(Category)与扩展(Extensions)

    一.类别(Category) 类别(Category)是一种可以为现有的类(包括类簇:NSString...,甚至源码无法获得的类)添加新方法的方式无需从现有的类继承子类.类别添加的新方法可以被子类继 ...

  8. 97、爬虫框架scrapy

    本篇导航: 介绍与安装 命令行工具 项目结构以及爬虫应用简介 Spiders 其它介绍 爬取亚马逊商品信息   一.介绍与安装 Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, ...

  9. scrapy爬虫学习系列二:scrapy简单爬虫样例学习

    系列文章列表: scrapy爬虫学习系列一:scrapy爬虫环境的准备:      http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_00 ...

随机推荐

  1. 堆优DIJ模板

    Dij:贪心思想的单源最短路,时间复杂度O(n^2). Dij算法流程: d数组记录源点s到每个点的距离,若无边则设为inf,标记源点: 选出d数组中未标记的最小值,该节点记为k,并标记k为已求出最短 ...

  2. z-index优先级小结

    z-index是深度属性,设置元素在z轴上面的堆叠顺序. 强调:z-index必须和定位元素position:absollute|relative|fixed一起使用,否则无效 1.z-index属性 ...

  3. python中编码判断

    https://www.cnblogs.com/lc-D-a/p/6074878.html python3 用isinstance()检查unicode编码报错

  4. Javascript 表达式中连续的 && 和 || 之赋值区别

    为了区分赋值表达式中出现的连续的 ‘&&’和 ‘||’的不同的赋值含义,做了一个小测试,代码如下: function write(msg){     for(var i = 0; i ...

  5. 有空要解决的错误log

    E/FaceSDK (): FACESDKTimer face score =0.999912 I/FaceTracker(): face_verification used: I/DEBUG ( ) ...

  6. 常胜将军的深思变局:OPPO的渐变释放了怎样的行业信号?

    在经过了前几年的狂飙突进后,当下手机行业已经步入了自身的"十年之痒"阶段.利润贴地飞行.T型格局已定且竞争者实力愈强.创新不明显导致消费者换新驱动力降低.全球化竞争趋势凸显-- 也 ...

  7. IOS下的safari下localStorage不起作用的问题

    我们的一个小应用,使用百度地图API获取到用户的坐标之后用localStorage做了下缓存,测试上线之后有运营同学反馈页面数据拉取不到, 测试的时候没有发现问题,而且2台相同的iphone一台可以一 ...

  8. 良知VS野心,苹果为何要翻新手机?

    前不久,苹果在大中华区推出了iPhone和iPad换机服务,消息一经发出便引发了果粉们的狂欢,那些丢弃在抽屉里的iPhone4S们看上去终于有着落了,也更坚定了"我是果粉,我骄傲" ...

  9. python ftp sftp

    ftp 上传下载文件 12345678910111213141516171819202122232425262728293031323334 from ftplib import FTPimport ...

  10. LeetCode43(字符串相乘)

    题目: 给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式. 示例 1: 输入: num1 = "2", ...