【Python从入门到进阶】45、Scrapy框架核心组件介绍

接上篇《44、Scrapy的基本介绍和安装》
上一篇我们学习了Scrapy框架的基础介绍以及环境的搭建,本篇我们来学习一下Scrapy框架的核心组件的使用。

下面的核心组件的介绍,仍是基于这幅图的机制,大家可以再回顾一下:

注:图片来自[寻_觅]博主

一、Item定义与处理

1.1 Item的概述

在Scrapy框架中,Item是数据的主要载体,用于存储Spider从网页爬取的数据。Item定义了数据的结构,并通过Item Loader对爬取到的数据进行加载和清洗。

1.2 Item的定义

Item使用Python类来定义,通常继承自scrapy.item.Item基础类。通过定义Item类,我们可以明确数据的结构,如字段、类型等。例如:

import scrapy  class MyprojectItem(scrapy.Item):  link = scrapy.Field()  # 字段名,数据类型默认为str  description = scrapy.Field()  # 字段名,数据类型默认为str

1.3 Item的处理

Item的处理主要涉及两个部分:Item Loader和Pipeline。Item Loader用于加载和清洗数据,Pipeline则负责数据的持久化存储。
Item Loader:Item Loader是用于加载和清洗数据的组件。通过使用Item Loader,我们可以对爬取到的数据进行预处理,如删除不需要的空白字符、转换数据类型等。使用Item Loader需要定义Loader类,并指定需要加载的字段。例如新建一个MySpider定义一个ItemLoader对象:

import scrapy
from scrapy.loader import ItemLoader
from ..items import MyprojectItemclass MySpider(scrapy.Spider):  name = 'myspider'  start_urls = ['http://example.com']  def parse(self, response):  loader = ItemLoader(item=MyprojectItem(), response=response)  # 使用XPath选择器选择<h1>标签中的内容作为标题。  loader.add_xpath('title', '//h1/text()')  # 使用CSS选择器选择class为content的元素中的内容作为内容。 loader.add_css('content', '.content')  return loader.load_item()

而Pipeline负责数据的持久化存储,如将爬取到的数据存储到数据库、文件等,我们在下面的小结详细讲解。

二、Spider爬虫定义与使用

2.1 Spider的概述

Spider是Scrapy框架中用于爬取网页数据的组件。Spider通过模拟浏览器行为,自动解析网页结构,提取所需的数据,并将其封装为Item对象。

2.2 Spider的编写

编写Spider需要继承scrapy.Spider基础类,并实现以下方法:

●name:Spider的唯一标识符,用于在Scrapy项目中区分不同的Spider。
●start_urls:爬取的起始URL列表。Scrapy会从这些URL开始爬取数据。
●parse():用于解析单个网页的回调函数。该函数将接收一个Response对象作为参数,并返回一个Item对象或一个Item生成器。

例如,以下是一个简单的Spider,用于爬取网站上的所有链接:

import scrapy
from ..items import MyprojectItemclass BaiduUrlSpider(scrapy.Spider):name = "baidu_url"allowed_domains = ["www.baidu.com"]start_urls = ["https://www.baidu.com"]def parse(self, response):# 抓取所有的链接for link in response.css('a::attr(href)').getall():if "http" in link or "https" in link:print("link: ", link)  # 打印出来抓取的链接地址item = MyprojectItem(link=link, description='test')yield item  # 把数据交给管道  piplines.py  进行数据的下载

2.3 Spider的使用

在Scrapy项目中,可以通过运行Scrapy命令来启动Spider:

●运行scrapy crawl <spider_name>命令,其中<spider_name>是Spider的名称。该命令将启动指定的Spider,并开始爬取数据。
●可以使用-o选项指定输出的文件名,例如scrapy crawl myspider -o output.csv将爬取的数据输出到output.csv文件中。
●可以使用-t选项指定输出数据的格式,例如scrapy crawl myspider -t csv将输出CSV格式的数据。

三、Pipeline数据处理管道

3.1 Pipeline的概述

Pipeline是Scrapy框架中负责处理已爬取数据的组件。它负责将爬取到的数据从Spider传递到最终的存储位置,并在传递过程中对数据进行清洗、验证和持久化。

3.2 Pipeline的工作流程

Pipeline的工作流程如下:

(1)Spider爬取数据完成后,将Item对象传递给Pipeline。
(2)Pipeline接收到Item对象后,会按照设定的顺序逐一进行处理。每个Pipeline都有一个唯一的优先级,优先级高的Pipeline会先于优先级低的Pipeline进行处理。
(3)在Pipeline中,可以对Item对象进行各种处理,如清洗数据、验证数据、持久化存储等。
(4)处理完成后,Pipeline将Item对象返回给Engine。
(5)Engine将Item对象传递给下一个Pipeline进行处理,或者将其传递给最终的存储位置。

3.3 自定义Pipeline

在Scrapy框架中,我们可以自定义Pipeline来满足特定的数据处理需求。要自定义Pipeline,需要创建一个Python类,并实现process_item()方法。process_item()方法接受一个Item对象作为参数,并返回一个Item对象。例如,我们可以创建一个将Item对象存储到CSV文件的Pipeline:
在settings.py中启用Pipeline:

ITEM_PIPELINES = {  'myproject.pipelines.MyPipeline': 300,  
}

分配给每个类的整型值,确定了他们运行的顺序,item按数字从低到高的顺序,通过pipeline,通常将这些数字定义在0-1000范围内(0-1000随意设置,数值越低,组件的优先级越高)
创建Pipeline类,item pipiline组件是一个独立的Python类,其中process_item()方法必须实现:

from scrapy.exporters import CsvItemExporter
import json  # 需要导入的
from collections import OrderedDict  # 需要导入的class MyPipeline(object):def __init__(self):# 可选实现,做参数初始化等self.file = open('news_data1.csv', 'wb')self.exporter = CsvItemExporter(self.file, encoding='gbk')self.exporter.start_exporting()def process_item(self, item, spider):# item (Item 对象) – 被爬取的item# spider (Spider 对象) – 爬取该item的spider# 这个方法必须实现,每个item pipeline组件都需要调用该方法,# 这个方法必须返回一个 Item 对象,被丢弃的item将不会被之后的pipeline组件所处理。print('默认的字段数据:{}\n'.format(item))item = OrderedDict(item)item = json.dumps(item, ensure_ascii=False)print('调整后的字段数据:{}\n'.format(item))self.exporter.export_item(eval(item))return item  # 返回一个Item对象,该对象将被持久化存储到CSV文件def open_spider(self, spider):# spider (Spider 对象) – 被开启的spider# 可选实现,当spider被开启时,这个方法被调用。passdef close_spider(self, spider):# spider (Spider 对象) – 被关闭的spider# 可选实现,当spider被关闭时,这个方法被调用self.exporter.finish_exporting()self.file.close()

四、Scheduler调度器

4.1 Scheduler的概述

Scheduler是Scrapy框架中的调度器组件,负责管理爬取任务的队列。它根据一定的优先级和规则,将爬取请求放入队列中,并按照顺序执行。

4.2 Scheduler的工作原理

Scheduler的工作原理如下:

(1)Spider爬取完一个网页后,将生成的请求(Request)对象传递给Scheduler。
(2)Scheduler根据请求的优先级、规则等因素,将其放入内部的队列中。
(3)Engine启动后,会定期从Scheduler中获取请求,并将其传递给下载器进行下载。
(4)下载完成后,Engine将下载的响应(Response)对象传递给Scheduler。
(5)Scheduler将响应对象传递给相应的Spider进行处理。

4.3 Scheduler的配置

在Scrapy项目的settings.py文件中,可以通过设置以下参数来配置Scheduler的行为:

●SCHEDULER:用于指定使用的Scheduler类。Scrapy框架提供了多种Scheduler的实现,如DumbScheduler、SqlalchemyScheduler等。可以根据需求选择合适的Scheduler。
●SCHEDULER_QUEUE_CLASS:用于指定请求队列的实现方式。Scrapy框架提供了多种队列的实现,如PriorityQueue、FifoQueue等。可以根据需求选择合适的队列。
●SCHEDULER_QUEUE_URL:用于指定请求队列的持久化存储方式。可以使用Redis、RabbitMQ等消息队列服务作为存储后端。
●SCHEDULER_PERSIST:用于指定是否启用请求队列的持久化存储。设置为True时,请求队列将在爬虫重启后继续存在,避免重复爬取。

4.4 自定义Scheduler

如果默认的Scheduler不能满足需求,我们可以自定义Scheduler来实现特定的调度逻辑。要自定义Scheduler,需要创建一个Python类,并实现以下方法:

●enqueue_request(request):将请求加入队列中。该方法需要返回一个布尔值,表示请求是否成功加入队列。
●dequeued_request():从队列中获取请求。该方法需要返回一个请求对象。
●has_pending_requests():检查队列中是否有待处理的请求。该方法需要返回一个布尔值。
●stats:返回调度器的统计信息。该方法需要返回一个字典,包含调度器的各种统计数据。

五、Downloader下载器

5.1 Downloader的概述

Downloader是Scrapy框架中负责下载网页数据的组件。它接收Engine传递的下载请求(Request),并发送HTTP请求到目标网站,获取网页的响应(Response)数据,并将其返回给Engine。

5.2 Downloader的工作流程

Downloader的工作流程如下:

(1)Engine将下载请求(Request)对象传递给Downloader。
(2)Downloader根据请求的URL、方法、头信息等,构建HTTP请求。
(3)Downloader发送HTTP请求到目标网站,并等待响应。
(4)一旦收到响应,Downloader将响应数据封装为Response对象,并将其返回给Engine。
(5)Engine将Response对象传递给相应的Spider进行处理。

5.3 Downloader的配置

在Scrapy项目的settings.py文件中,可以通过设置以下参数来配置Downloader的行为:

●DOWNLOADER:用于指定使用的Downloader类。Scrapy框架默认使用scrapy.core.downloader.handlers.http.HTTPDownloader作为Downloader的实现。
●DOWNLOAD_DELAY:用于设置下载器在连续下载请求之间的延迟时间(秒)。这可以避免对目标网站造成过大的访问压力。
●DOWNLOAD_TIMEOUT:用于设置下载请求的超时时间(秒)。如果请求在超时时间内没有响应,Downloader将引发超时异常。
●DOWNLOADER_MIDDLEWARES:用于指定使用的Downloader中间件列表。Downloader中间件可以对下载请求和响应进行预处理和后处理,例如添加代理、处理重定向等。
●DOWNLOADER_MIDDLEWARES_BASE:Scrapy框架提供的默认Downloader中间件列表。可以在自定义的Downloader中间件中继承或覆盖默认的中间件。

5.4 自定义Downloader

如果默认的Downloader不能满足需求,我们可以自定义Downloader来实现特定的下载逻辑。要自定义Downloader,需要创建一个Python类,并实现以下方法:

●fetch(request, spider):用于处理下载请求。该方法需要接收一个Request对象和一个Spider对象作为参数,并返回一个包含响应数据的Response对象。在该方法中,可以使用Python标准库中的HTTP客户端库(如urllib、requests等)来发送HTTP请求,并获取响应数据。
●close():用于在Downloader关闭时进行清理操作。该方法可选,可以根据需要进行实现。

通过自定义Downloader,我们可以实现更复杂的下载逻辑,例如使用代理、处理验证码、处理动态加载等。

六、Engine引擎

6.1 Engine的概述

Engine是Scrapy框架的核心组件,负责协调和控制整个爬取过程。它管理着Spider、Scheduler、Downloader和Pipeline等组件,确保它们按照正确的顺序和逻辑进行工作。

6.2 Engine的工作流程

Engine的工作流程如下:

(1)初始化Engine,并加载Scrapy项目的配置。
(2)加载并启动Spider,将Spider的起始URL传递给Scheduler。
(3)从Scheduler中获取下一个要爬取的请求(Request)。
(3)将请求传递给Downloader进行下载。
(4)等待Downloader返回响应(Response)。
(5)将响应传递给相应的Spider进行处理。
(6)Spider解析响应数据,提取所需的信息,并生成新的请求或Item对象。
(7)将新生成的请求传递给Scheduler进行调度。
(8)将生成的Item对象传递给Pipeline进行处理。
(9)重复步骤3-9,直到Scheduler中没有更多的请求或满足停止条件。
(10)关闭Engine,释放资源。

6.3 Engine的配置

在Scrapy项目的settings.py文件中,可以通过设置以下参数来配置Engine的行为:

●CONCURRENT_REQUESTS:用于设置同时进行的下载请求数量。该参数可以控制并发度,即Downloader同时处理的请求数量。
●CONCURRENT_REQUESTS_PER_DOMAIN:用于设置每个域名同时进行的下载请求数量。该参数可以限制对同一网站的并发访问量,避免对目标网站造成过大的访问压力。
●CONCURRENT_REQUESTS_PER_IP:用于设置每个IP地址同时进行的下载请求数量。该参数可以进一步细化对并发访问量的控制,限制对同一IP地址的请求频率。
●DOWNLOAD_TIMEOUT:用于设置下载请求的超时时间(秒)。如果请求在超时时间内没有响应,Engine将引发超时异常。
●ENGINE_STOPPER:用于指定Engine的停止条件。可以自定义一个类,并实现should_stop()方法来判断是否满足停止条件。

6.4 自定义Engine

在Scrapy框架中,一般情况下不需要自定义Engine,因为Engine的核心功能已经由框架提供,并且可以通过配置参数进行调整。但是,如果需要实现特殊的爬取逻辑或集成其他功能,可以通过继承Scrapy的Engine类来自定义Engine。自定义Engine时,可以重写start()和stop()方法来实现自定义的启动和停止逻辑,也可以重写其他方法来扩展Engine的功能。需要注意的是,自定义Engine需要熟悉Scrapy框架的内部工作原理和各个组件之间的交互方式。

七、Logging日志系统

7.1 日志系统的概述

日志系统是Scrapy框架中用于记录和跟踪爬虫运行信息的组件。通过日志系统,我们可以方便地查看爬虫的运行状态、调试问题、监控异常等。

7.2 日志级别的概念

Scrapy的日志系统使用Python的标准库logging模块实现,支持多种日志级别,包括:

●DEBUG:详细信息,用于开发和调试阶段。
●INFO:一般信息,用于了解爬虫的运行情况。
●WARNING:警告信息,用于指出可能的问题或异常。
●ERROR:错误信息,用于记录发生的错误。
●CRITICAL:严重错误,用于记录严重的问题或异常。

7.3 日志配置

在Scrapy项目的settings.py文件中,可以通过设置以下参数来配置日志系统的行为:

●LOG_LEVEL:用于设置日志级别。可选值包括DEBUG、INFO、WARNING、ERROR、CRITICAL。默认级别为WARNING。
●LOG_FILE:用于指定日志文件的路径。如果设置了这个参数,日志将输出到指定的文件中。
●LOG_ENABLED:用于启用或禁用日志功能。设置为True时,启用日志功能;设置为False时,禁用日志功能。默认值为True。
●LOG_STDOUT:用于将日志输出到标准输出(stdout)。设置为True时,将日志输出到控制台;设置为False时,不输出到控制台。默认值为False。
●LOG_FORMAT:用于设置日志的格式。格式化字符串可以根据需要自行定制,支持%levelname、%message等占位符。

7.4 自定义日志处理程序

如果默认的日志处理程序不能满足需求,我们可以自定义一个处理程序来自定义日志的行为。要自定义日志处理程序,需要创建一个Python类,并实现以下方法:

●__init__(self, logger, log_level, log_format):初始化方法,接收一个logger对象、一个log_level参数和一个log_format参数。
●handle(self, record):处理日志记录的方法。该方法接收一个Record对象作为参数,并返回一个处理后的日志记录对象。可以对该方法进行重写,实现自定义的日志处理逻辑。

通过自定义日志处理程序,我们可以对日志进行更详细的处理和定制化输出,例如将日志发送到远程服务器、将日志写入数据库等。

八、测试

刚刚上面定义的item、itemloder、spiders、pipelines跑一下试试:

在控制台输入:scrapy crawl baidu_url,效果(日志LOG_LEVEL = "ERROR"):

下载的csv文件内容:

成功的获取了百度首页的所有链接信息。

至此,我们对Scrapy框架的核心组件介绍就完毕了。下一篇我们以58同城网站抓取为样例,写一个实际案例来训练Scrapy框架的使用。

转载请注明出处:https://guangzai.blog.csdn.net/article/details/135187400

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

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

相关文章

设计模式 建造者模式 与 Spring Bean建造者 BeanDefinitionBuilder 源码与应用

建造者模式 定义: 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示主要作用: 在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象如何使用: 用户只需要给出指定复杂对象的类型和内容, 建造者模式负责按顺序创建复杂对象…

Spring Cloud + Vue前后端分离-第7章 核心业务功能开发

Spring Cloud Vue前后端分离-第7章 核心业务功能开发 7-1 课程管理功能开发 课程管理页面美化 1.课程管理页面美化 demo-course.jpg 复制search.html中的部分代码 course.vue 看效果 测试一下新增修改删除效果 1.课程管理页面美化2 scoped:style下的样式只应用于当前组件…

BUG记录 | 使用阿里云OSS实现文件上传后,得到的url无法在浏览器中打开

项目背景 SpringBoot的项目&#xff0c;使用阿里云对象存储OSS对项目中的文件进行存储&#xff0c;所需文件也会通过IDEA中由官方Demo改编而成的工具类作为接口&#xff0c;调用接口后上传 问题描述 使用阿里云OSS实现文件上传后&#xff0c;通过postman测试得到的url无法在…

MyBatis动态sql中foreach标签介绍和使用

MyBatis动态sql中foreach标签介绍和使用 参数解释&#xff1a; foreach 的主要作用在构建 in 条件中&#xff0c;它可以在 sql 语句中进行迭代一个集合。foreach 元素的属性主要有 collection&#xff0c;item&#xff0c;separator&#xff0c;index&#xff0c;open&#x…

怎么做好数字化工厂的建设?

怎样建设好的数字化工厂&#xff0c;不但须要有充足的费用预算&#xff0c;更加需要科学研究的计划和设计方案&#xff0c;一般做好智能化基本建设&#xff0c;务必要根据下列流程&#xff1a; 一.信息管理系统的计划和设计方案   许多的工厂会购买许多的单独的信息管理系统&…

CreateProcess error=216, 该版本的 %1 与你运行的 Windows 版本不兼容。请查看计算机的系统信息,然后联系软件发布者。

第一个go程序就出错了&#xff0c;错误提示&#xff1a; Error running ‘go build hello.go’: Cannot run program “C:\Users\Administrator\AppData\Local\Temp___go_build_hello_go.exe” (in directory “G:\go\workspace”): CreateProcess error216, 该版本的 %1 与你运…

【面向对象】对比JavaScript、Go、Ada、Python、C++、Java、PHP的访问限制。

在不同编程语言中&#xff0c;控制成员&#xff08;变量、方法、类等&#xff09;可见性的机制不尽相同。以下是对比JavaScript、Go、Ada、Python、C、Java、PHP所使用的访问限制关键字和约定&#xff1a; 一、JavaScript ### JavaScript访问限制 早期的JavaScript并没有类似…

Python 运维(三):使用 zipapp 将 Python 程序打包成单个可执行文件

大家好&#xff0c;我是水滴~~ 在 Python 开发中&#xff0c;我们经常需要将应用程序打包成可执行文件&#xff0c;以便在不具备 Python 环境的计算机上运行。Python 提供了多种打包工具&#xff0c;其中之一就是 zipapp。zipapp 可以将 Python 应用程序及其依赖打包成一个单独…

Spring5底层原理之BeanFactory与ApplicationContext

目录 BeanFactory与ApplicationContext BeanFactory ApplicationContext 容器实现 BeanFactory实现 ApplicationContext实现 ClassPathXmlApplicationContext的实现 AnnotationConfigApplicationContext的实现 AnnotationConfigServletWebServerApplicationContext的实…

【项目管理】CMMI-需求跟踪矩阵模版

需求菜单/功能模块需求名称需求变更类型&#xff08;新增、修改&#xff09;需求状态&#xff08;已建议、已批准、已设计、已实现、已验证、已删除&#xff09;优先级&#xff08;高、中、低&#xff09;软件需求&#xff08;工作产品、章节号&#xff09;概要设计&#xff08…

听GPT 讲Rust源代码--src/tools(25)

File: rust/src/tools/clippy/clippy_lints/src/methods/suspicious_command_arg_space.rs 在Rust源代码中&#xff0c;suspicious_command_arg_space.rs文件位于clippy_lints工具包的methods目录下&#xff0c;用于实现Clippy lint SUSPICIOUS_COMMAND_ARG_SPACE。 Clippy是Ru…

【计算机网络】网络层——IP协议

目录 一. 基本概念 二. 协议报文格式 三. 网段划分 1. 第一次划分 2. CIDR方案 3. 特殊的IP地址 四. IP地址不足 1. 私有IP和公网IP 2. DHCP协议 3. 路由器 4. NAT技术 内网穿透(NAT穿透) 五. 路由转发 路由表生成算法 结束语 一. 基本概念 IP指网络互连协议…