爬虫工作量由小到大的思维转变---<第二十四章 Scrapy的`统计数据`收集stats collection>

前言:

前两篇是讲的数据诊断分析,还有一篇深挖`解决内存泄漏`的文章,目前我还没整理汇编出来;但是,想到分析问题的时候,忽然觉得`爬虫的数据统计`好像也挺重要;于是,心血来潮准备来插一篇这个------让大家对日常scrapy爬的数据,做到心里有数!不必自己去搅破脑汁捣腾日志,敲计算器了;

正文:

在 Scrapy 中,可以使用 Stats Collection(统计信息收集)来收集和获取有关爬虫运行过程中的统计信息。Stats Collection 提供了各种默认的统计指标,例如请求数量、下载时间和爬取成功数等。

当然,也可以使用其他的,例如:

MemoryStatsCollector:默认的统计收集器,将统计数据存储在内存中。
CsvStatsCollector:将统计数据保存为 CSV 格式的文件。
JsonLinesStatsCollector:将统计数据保存为 JSON Lines 格式的文件。
XmlStatsCollector:将统计数据保存为 XML 格式的文件。
DbStatsCollector:将统计数据保存到数据库中。
LogStatsCollector:通过日志输出统计数据。
-----这些其实都大同小异,我们就拿第一个来开刀!!

使用 Stats Collection 的步骤:

1. 在 Scrapy 项目的配置文件 `settings.py` 中启用 Stats Collection:

   STATS_CLASS = 'scrapy.statscollectors.MemoryStatsCollector'

通过配置 `STATS_CLASS` 参数,可以选择不同的 Stats Collector。在示例中,我们使用了 `MemoryStatsCollector`,该 Collector 将统计信息存储在内存中。

2. 在 Scrapy 的爬虫代码中导入 `scrapy.stats`:

   from scrapy import stats

3. 在爬虫代码中,可以使用 `stats` 对象来访问和处理统计信息。以下是一些常用的方法:
  •    - `stats.get_value(key, default=None)`:获取指定键名的统计值。如果指定的键名不存在,则返回提供的 `default` 值(默认为 `None`)。
  •    - `stats.inc_value(key, count=1)`:增加指定键名的统计值。`count` 参数可以指定增加的数量,默认为 1。
  •    - `stats.set_value(key, value)`:设置指定键名的统计值为给定的 `value`。
  •    - `stats.get_stats()`:返回当前所有统计信息的字典形式。

使用 Stats Collection:

   from scrapy import Spiderfrom scrapy import statsclass MySpider(Spider):name = 'my_spider'start_urls = ['http://example.com']def parse(self, response):# 增加请求数量统计值self.stats.inc_value('request_count')# 获取当前请求数量的统计值request_count = self.stats.get_value('request_count', default=0)self.logger.info(f"Request Count: {request_count}")# 设置自定义统计值self.stats.set_value('custom_stat', 10)# 获取所有统计信息all_stats = self.stats.get_stats()self.logger.info(f"All Stats: {all_stats}")# ...其他处理代码...```

     在上述示例中,在解析函数中使用 `stats` 对象进行统计值的增加、获取和设置操作,以及获取所有统计信息。可以根据需要进行自定义的统计值操作,从而监控和分析爬虫的运行情况。

ps:Stats Collection 默认收集的统计信息可能会消耗一定的内存,如果需要更复杂的统计需求,可以考虑使用第三方库或自定义 Stats Collector 进行更高级的统计处理。


深入:

当需要进行更高级的统计处理时,可以自定义 Stats Collector 来满足特定的需求。自定义 Stats Collector 可以用于收集、处理和保存统计数据,以便后续分析和可视化。

以下是自定义 Stats Collector 的步骤:

1. 创建一个自定义的 Stats Collector 类,继承自 `scrapy.statscollectors.StatsCollector` 类,并重写需要的方法。

通常情况下,需要实现 `__init__()`、`open_spider()`、`close_spider()` 和 `get_value()` 方法。

 from scrapy.statscollectors import StatsCollectorclass CustomStatsCollector(StatsCollector):def __init__(self, crawler):super().__init__(crawler)# 初始化自定义的统计数据self.custom_stats = {}def open_spider(self, spider):super().open_spider(spider)# 初始化每个爬虫的自定义统计数据self.custom_stats[spider.name] = {}def close_spider(self, spider, reason):super().close_spider(spider, reason)# 在爬虫结束时处理自定义统计数据custom_stats_data = self.custom_stats[spider.name]# 进行进一步的处理或保存操作def get_value(self, key, default=None, spider=None):# 获取自定义统计数据的值if spider:return self.custom_stats[spider.name].get(key, default)return default


  

2. 在 Scrapy 项目的配置文件 `settings.py` 中配置自定义的 Stats Collector 类:

   STATS_CLASS = 'your_project_name.custom_stats.CustomStatsCollector'

  ps:`your_project_name` 需要替换为 Scrapy 项目的名称,以及其他必要的导入路径。

3. 使用自定义的 Stats Collector

   在 Spider 类中,通过 `self.crawler.stats` 访问自定义的 Stats Collector 对象,并使用相应的方法进行统计值的获取、增加和设置。

   from scrapy import Spiderclass MySpider(Spider):name = 'my_spider'start_urls = ['http://example.com']def parse(self, response):# 增加自定义统计值self.crawler.stats.inc_value('custom_stat', spider=self)# 获取自定义统计值custom_stat_value = self.crawler.stats.get_value('custom_stat', default=0, spider=self)self.logger.info(f"Custom Stat Value: {custom_stat_value}")# 设置自定义统计值self.crawler.stats.set_value('custom_stat', 10, spider=self)# ...其他处理代码...


   创建一个自定义的 Stats Collector 类 `CustomStatsCollector`,并在 `open_spider()` 和 `close_spider()` 方法中进行自定义统计数据的初始化和处理。在 Spider 类中,使用 `self.crawler.stats` 访问自定义的 Stats Collector 对象,并用相应的方法进行自定义统计值的增加、获取和设置。

也可以根据具体需求在自定义 Stats Collector 类中添加其他统计方法和处理逻辑,并使用自定义统计数据进行进一步的分析和处理。

另一个案例:

统计每个爬虫访问 URL 的数量,并在爬虫结束时将统计数据保存到文件中。

import json
from scrapy.statscollectors import StatsCollectorclass CustomStatsCollector(StatsCollector):def __init__(self, crawler):super().__init__(crawler)# 初始化自定义统计数据self.custom_stats = {}def open_spider(self, spider):super().open_spider(spider)# 初始化每个爬虫的自定义统计数据self.custom_stats[spider.name] = {'url_count': 0}def close_spider(self, spider, reason):super().close_spider(spider, reason)# 在爬虫结束时处理自定义统计数据custom_stats_data = self.custom_stats[spider.name]# 保存自定义统计数据到文件with open(f'{spider.name}_stats.json', 'w') as file:json.dump(custom_stats_data, file)def inc_url_count(self, spider):# 增加 URL 数量统计值self.custom_stats[spider.name]['url_count'] += 1def get_url_count(self, spider):# 获取 URL 数量统计值return self.custom_stats[spider.name]['url_count']

在 Spider 类中,我们可以调用自定义 Stats Collector 的 `inc_url_count()` 方法来增加 URL 数量的统计值,并使用 `get_url_count()` 方法获取统计值。

from scrapy import Spiderclass MySpider(Spider):name = 'my_spider'start_urls = ['http://example.com']def parse(self, response):# 增加 URL 数量统计值self.crawler.stats.inc_url_count(self)# 获取 URL 数量统计值url_count = self.crawler.stats.get_url_count(self)self.logger.info(f"URL Count: {url_count}")# ...其他处理代码...


在这个案例中,我们定义了 `CustomStatsCollector` 类,用于统计每个爬虫访问的 URL 数量。使用 `inc_url_count()` 方法增加统计值,并使用 `get_url_count()` 方法获取统计结果。在爬虫结束时,自定义统计数据将被保存到以爬虫名为前缀的 JSON 文件中。

(可自行在此框架上修改,自己需要的业务逻辑)


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/408046.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uva 10245 The Closest Pair Problem_枚举

题意&#xff1a;求任意两点之间的距离的最少一个距离 思路&#xff1a;枚举一下就可以了 #include <iostream> #include<cstdio> #include<cmath> using namespace std; #define N 10010 struct node{double x,y; }p[N]; int main(int argc, char** argv) {…

react学习(70)--拼接方式

const tabs [{ key: , value: 全部 }, ...MERCHANTLISTSTARTUS];

.Net开发人员应该下载的十种必备工具(一)

用于编写单元测试的 NUnit用于创建代码文档资料的 NDoc用于生成解决方案的 NAnt用于生成代码的 CodeSmith用于监视代码的 FxCop用于编译少量代码的 Snippet Compiler两种不同的转换器工具&#xff1a;ASP.NET 版本转换器和 Visual Studio .NET 项目转换器用于生成正则表达式的 …

旋转根组件 Learn Unreal Engine (with C++)

旋转根组件 Learn Unreal Engine (with C) 在UE4中,根组件是无法旋转定位的,只能够缩放,在一些情况下,我们有旋转根组件的需求 SpaceshipBattle fanxingin/UE4项目 - 码云 - 开源中国 (gitee.com) 旋转根组件 将SceneComponent设为根组件 然后将StaticMeshComponentattach…

2007.2.14 日程安排

公元二零零七年二月十四日&#xff0c;农历腊月二十七&#xff0c;该天尤为特别&#xff0c;乃春节长假之初始。此外&#xff0c;该天将是片地鸳侣&#xff0c;漫天桃花之好时日&#xff0c;于是吾将广纳四方真气&#xff0c;闭关修炼&#xff0c;与世无争。00&#xff1a;00 -…

react学习(71)--render使用

title: 品牌资质有效期,dataIndex: certificationStartDate,render: (text, row) > {return (<span>{moment(row.certificationStartDate).format(YYYY-MM-DD)}-{moment(row.certificationEndDate).format(YYYY-MM-DD)}</span>);},

2014.3.5-C语言学习小结

知识点:1.结构体 struct2.联合体 union3.枚举4.结构、联合与函数结构体思考:如果现在希望保存一个学生的信息,该如何保存sprintf "zhangsan:18:180”%s:%d:%d, name, height, agechar name[10][100]int age[10]int height[10]1.什么是结构体 struct结构体指的是一种数据结…

什么是Tomcat?

如今&#xff0c;基于Web的应用越来越多&#xff0c;传统的Html已经满足不了如今的需求。我们需要一个交互式的Web&#xff0c;于是便诞生了各种Web语言。如Asp&#xff0c;Jsp&#xff0c;Php等。当然&#xff0c;这些语言与传统的语言有着密切的联系&#xff0c;如Php基于C和…

react学习(72)--row上面加样式

<Row><Col><Buttonstyle{{marginTop: 24px,marginBottom: 24px,float: right,marginRight: 24px,}}type"primary"onClick{this.addApply}>新增申请</Button></Col></Row>

禁止摄像机跟随`Actor`旋转 Learn Unreal Engine (with C++)

禁止摄像机跟随Actor旋转 Learn Unreal Engine (with C) SpaceshipBattle fanxingin/UE4项目 - 码云 - 开源中国 (gitee.com) 如果直接将摄像机绑定在根组件上,在根组件旋转时,摄像机也会跟着旋转 那么如何让摄像机不跟随根组件旋转,只跟着根组件移动 禁止摄像机跟随根组件…

大脑可以自动修复酗酒造成的脑细胞损坏

英国路透社报道&#xff0c;国际科研小组研究发现&#xff0c; 过量饮酒会损坏大脑细胞&#xff0c;而大脑本身可以修复一些损坏。但他们警告酗酒者应该尽快清醒&#xff0c;因为持续大量饮酒的时间越长&#xff0c;大脑对损坏的修复能力越弱。“这项研究传达给酗酒者的主要信息…

邮件发送---在.net2003和2005中

smtpClient发邮件错误&#xff1a;不允许使用邮箱名称。 服务器响应为: You are not authorized to send mail, authentication is required 使用smtpClient发送邮件时&#xff0c;经常跑出难以明白的错误。其实主要都和我们申请的免费邮箱有关系。有些邮箱不支持&#xff0c;…

开发人员如何成为架构师

很多架构师都是从好的开发人员逐步过渡而来的&#xff0c;但并非每个好的开发人员都希望成为架构师&#xff0c;而且他们并不是都适合做架构师。无论您是打算进行职业转型的开发人员&#xff0c;还是寻找能承担体系结构设计责任的合适人选的经理&#xff0c;都务必对此转型过程…

WSL2 安装中文输入法教程 简单有效

很多教程我都参考过 大多有问题 只有这个简单明了实用 WSL2安装中文输入法教程 https://monkeywie.cn/2021/09/26/wsl2-gui-idea-config/

VB2005.Net 环境下使用Jmail组件发送邮件

配置环境&#xff1a;.Net Framework 2.0 测试版2&#xff0c;w3Jmail4.4&#xff0c;Windows XP (sp2) 使用过程:1.首先安装jmail4.4 2.找到jmail.dll&#xff08;安装目录下&#xff09;copy 到D:/Microsoft Visual Studio 8/SDK/v2.0/Bin 目录下 3.假设你把Visual Basic …

好片与烂片

短短的几天&#xff0c; 就看到这么多的留言&#xff0c; 其实是有点喜出望外的&#xff0c;因为&#xff0c; 我在上传这些文字的时候&#xff0c; 是怀着一种惴惴然和惶恐的心情的&#xff0c;因为&#xff0c; 我不知道我的“谬论”是否可以登上大雅之堂&#xff0c;是否能…

react学习(73)--子组件this

componentDidMount() {console.log(this.props, props);console.log(this, this);this.props.onRef && this.props.onRef(this);}

C++ 17 inline static 实现单例模式

C 17 inline 内联定义静态变量 正在学习C20新标准,突然看到C17拓展inline变量,突然想到可不可以在类内部直接初始化静态变量,整个单例模式呢 不需要在类外部初始化静态变量 实现懒加载,需要的时候才加载 线程安全 外部无法调用构造函数,析构函数 代码如下: /** 多线程条…