当前位置: 首页 > news >正文

【Python】如何编写一个Scrapy扩展(Scrapy Extension)


曾经在幽幽暗暗
反反复复中追问
才知道平平淡淡
从从容容才是真
再回首恍然如梦
再回首我心依旧
只有那无尽的长路伴着我
                     🎵 姜育恒《再回首》


Scrapy是一个强大的爬虫框架,它不仅易于使用,而且具有高度的可扩展性。Scrapy的扩展机制允许开发者在爬虫的不同阶段插入自定义的功能,以实现特定的需求。本文将介绍如何编写一个Scrapy扩展,并展示一个实际的例子。

什么是Scrapy扩展

Scrapy扩展是一些可以插入到Scrapy的执行流程中的插件,用于在特定的时机执行自定义代码。这些时机包括引擎启动和停止、调度器事件、下载器事件以及爬虫的各种信号。

创建Scrapy扩展的步骤

  • 编写扩展类
  • 注册扩展
  • 配置Scrapy使用扩展

步骤1:编写扩展类

首先,我们需要创建一个扩展类,这个类将包含我们希望在特定时机执行的代码。以下是一个简单的扩展示例,它在爬虫开始和结束时打印日志信息。

import logging
from scrapy import signalsclass MyCustomExtension:def __init__(self, stats):self.stats = statsself.logger = logging.getLogger(__name__)@classmethoddef from_crawler(cls, crawler):ext = cls(crawler.stats)crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened)crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed)return extdef spider_opened(self, spider):self.logger.info(f"Spider {spider.name} opened: {spider}")def spider_closed(self, spider):self.logger.info(f"Spider {spider.name} closed: {spider}")

在这个扩展中,我们定义了两个方法 spider_opened 和 spider_closed,它们分别在爬虫开启和关闭时被调用。通过 signals.connect 方法,我们将这两个方法与 Scrapy 的 spider_opened 和 spider_closed 信号连接起来。

步骤2:注册扩展

接下来,我们需要在 settings.py 文件中注册我们的扩展。

EXTENSIONS = {'my_project.extensions.MyCustomExtension': 500,
}

这里的 500 是扩展的优先级,数值越小优先级越高。

步骤3:配置Scrapy使用扩展

在 settings.py 文件中,还需要确保我们的扩展能够被 Scrapy 识别和使用。如果没有特殊需求,已经完成的注册步骤即可使扩展生效。

完整示例

为了更好地理解整个过程,我们将创建一个完整的 Scrapy 项目,并添加我们的自定义扩展。

创建Scrapy项目
scrapy startproject my_project
创建扩展文件

在 my_project/my_project/extensions 目录下创建一个 init.py 文件,并添加以下代码:

# my_project/my_project/extensions/__init__.pyimport logging
from scrapy import signalsclass MyCustomExtension:def __init__(self, stats):self.stats = statsself.logger = logging.getLogger(__name__)@classmethoddef from_crawler(cls, crawler):ext = cls(crawler.stats)crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened)crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed)return extdef spider_opened(self, spider):self.logger.info(f"Spider {spider.name} opened: {spider}")def spider_closed(self, spider):self.logger.info(f"Spider {spider.name} closed: {spider}")
配置settings.py

在 my_project/my_project/settings.py 中添加扩展配置:

EXTENSIONS = {'my_project.extensions.MyCustomExtension': 500,
}
编写爬虫

创建一个简单的爬虫,在 my_project/my_project/spiders 目录下创建一个 example.py 文件,并添加以下代码:

import scrapyclass ExampleSpider(scrapy.Spider):name = "example"start_urls = ['http://quotes.toscrape.com/']def parse(self, response):for quote in response.css('div.quote'):yield {'text': quote.css('span.text::text').get(),'author': quote.css('small.author::text').get(),}
运行爬虫

在终端中运行以下命令,查看扩展的日志输出:

scrapy crawl example

你将看到类似以下的输出:

2024-07-26 12:00:00 [my_project.extensions] INFO: Spider example opened: <ExampleSpider 'example' at 0x10b2c4f70>
2024-07-26 12:00:10 [my_project.extensions] INFO: Spider example closed: <ExampleSpider 'example' at 0x10b2c4f70>

总结

本文介绍了如何编写和使用一个Scrapy扩展。通过扩展机制,我们可以在Scrapy的执行过程中插入自定义的逻辑,满足各种特定需求。希望这个示例能帮助你更好地理解和使用Scrapy扩展。如果你有任何问题或建议,欢迎在评论区留言。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 如何从PyTorch迁移到MindSpore
  • 求值(河南萌新2024)
  • (面试必看!)锁策略
  • python爬虫入门(五)之Re解析
  • Kafka 消费者启动后与服务器的交互流程
  • python实现提取视频帧的图片
  • vue3 主页面 跳转到子页面后 ,再次切换到主页面后 主页面及其它的所有页面 竟然不显示了的解决。
  • 企业做数据治理的意义是什么
  • 计算机网络必会面经
  • springboot业务层service开发全过程(以mybatis-plus为例)
  • EF访问PostgreSql,如何判断jsonb类型的数组是否包含某个数值
  • k8s学习--k8s集群部署kubesphere的详细过程
  • 2024.8.1(前端服务器的配置以及tomcat环境的配置)
  • 对象转化成base64-再转回对象
  • 人数管控系统助力图书馆实现精准客流统计分析
  • .pyc 想到的一些问题
  • [case10]使用RSQL实现端到端的动态查询
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • [译]Python中的类属性与实例属性的区别
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • Date型的使用
  • ES学习笔记(12)--Symbol
  • flutter的key在widget list的作用以及必要性
  • gf框架之分页模块(五) - 自定义分页
  • iOS 系统授权开发
  • mongodb--安装和初步使用教程
  • PhantomJS 安装
  • PHP 的 SAPI 是个什么东西
  • Python进阶细节
  • SegmentFault 2015 Top Rank
  • sessionStorage和localStorage
  • Travix是如何部署应用程序到Kubernetes上的
  • tweak 支持第三方库
  • Vue ES6 Jade Scss Webpack Gulp
  • vue的全局变量和全局拦截请求器
  • Vue--数据传输
  • 测试开发系类之接口自动化测试
  • 大主子表关联的性能优化方法
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 回顾2016
  • 基于 Babel 的 npm 包最小化设置
  • 记录一下第一次使用npm
  • 今年的LC3大会没了?
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 前端自动化解决方案
  • 探索 JS 中的模块化
  • 网络应用优化——时延与带宽
  • 无服务器化是企业 IT 架构的未来吗?
  • FaaS 的简单实践
  • MyCAT水平分库
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • ​flutter 代码混淆
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • ​如何使用QGIS制作三维建筑