深入解读 Scrapy 框架原理与源码

news2024/12/29 11:43:18

🛠️ Scrapy 框架原理解读

Scrapy 是一个强大的 Python 爬虫框架,其设计理念基于事件驱动的异步编程,通过高度模块化的方式实现爬虫功能。Scrapy 框架的核心组成包括爬虫(Spider)、调度器(Scheduler)、下载器(Downloader)、管道(Pipeline)和中间件(Middleware)。每个组件在数据抓取的过程中扮演不同的角色,从请求的生成、处理到数据的存储,整个流程经过了多个阶段,每个阶段都可以通过中间件进行扩展和修改。
在这里插入图片描述

爬虫(Spider): 爬虫是 Scrapy 的核心,负责定义爬取逻辑,包括请求的生成和响应的解析。它通过回调函数处理响应,并提取数据或生成新的请求。

调度器(Scheduler): 调度器的主要职责是接收请求并将其排队,等待下载器处理。它会按照请求的优先级和调度策略管理请求队列。

下载器(Downloader): 下载器负责发送 HTTP 请求并接收响应。它将响应传递给爬虫,爬虫再根据业务逻辑进行数据处理。

管道(Pipeline): 管道用于处理爬虫提取的数据。它可以进行数据清洗、验证、存储等操作。每个管道的优先级可以配置,以控制数据处理的顺序。

中间件(Middleware): 中间件在请求和响应处理的过程中插入自定义逻辑。它可以在请求发送前修改请求,在响应返回前处理响应,或者处理异常。

Scrapy 的这种设计使得爬虫的构建和维护变得更加灵活和可扩展。下面我们将深入解析 Scrapy 的运行原理和底层实现。


🚀 Scrapy 运行原理

Scrapy 的运行过程包括以下主要步骤:

  1. 请求生成: 爬虫定义的初始请求通过调度器(Scheduler)排队,等待下载器(Downloader)处理。

  2. 请求下载: 下载器从调度器中取出请求,发送 HTTP 请求,并获取响应数据。

  3. 响应处理: 下载器将响应传递给爬虫(Spider),爬虫解析响应数据,提取有用信息,并可能生成新的请求。

  4. 数据处理: 爬虫将提取的数据传递给管道(Pipeline),进行清洗、验证和存储操作。

  5. 数据存储: 数据处理完成后,管道将数据保存到数据库、文件系统或其他存储介质中。

请求生成: 爬虫通过定义 start_requests 方法或者 parse 回调函数生成初始请求。这些请求被传递到调度器中。

请求下载: 下载器会从调度器中取出请求,使用异步 I/O 技术(如 Twisted)发送请求,并获取响应。响应会被传递回爬虫。

响应处理: 爬虫通过回调函数(如 parse 方法)处理响应数据。爬虫可以从响应中提取数据,并生成新的请求以继续抓取。

数据处理: 数据处理由管道完成。Scrapy 提供了默认管道(如 JsonItemExporter)和允许用户自定义管道。管道的优先级决定了数据处理的顺序。


📜 Scrapy 底层源码解析

Scrapy 的底层实现依赖于 Twisted 异步框架,主要通过以下核心类来实现其功能:

CrawlerProcess

CrawlerProcess 是 Scrapy 的一个高层接口,用于启动爬虫进程。它封装了爬虫的创建、启动和管理过程。下面是一个简单的示例:

from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings

process = CrawlerProcess(get_project_settings())
process.crawl('my_spider')
process.start()

CrawlerRunner

CrawlerRunner 是一个较底层的类,用于在事件循环中管理多个爬虫。它允许同时运行多个爬虫并进行调度。

from scrapy.crawler import CrawlerRunner
from twisted.internet import reactor

runner = CrawlerRunner()
runner.crawl('my_spider')
runner.join().addCallback(lambda _: reactor.stop())
reactor.run()

Crawler

Crawler 是 Scrapy 的爬虫类,用于定义抓取逻辑。它包含了请求的生成和响应的处理逻辑。以下是一个自定义爬虫的示例:

import scrapy

class MySpider(scrapy.Spider):
    name = 'my_spider'
    
    def start_requests(self):
        urls = ['http://example.com/page1', 'http://example.com/page2']
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        title = response.css('title::text').get()
        yield {'title': title}

🛡️ Scrapy 中间件原理解读

Scrapy 的中间件是一种强大的机制,允许用户在请求和响应的处理过程中插入自定义逻辑。中间件可以分为下载中间件和响应中间件,它们分别处理请求和响应的不同阶段。

🌐 下载和响应中间件

  • 下载中间件: 负责处理请求的发送和响应的接收。主要方法包括 process_requestprocess_responseprocess_request 在请求发送之前被调用,process_response 在响应返回之前被调用。

  • 响应中间件: 主要负责处理响应内容的进一步操作,如解析响应、处理重定向等。主要方法包括 process_exception,用于处理请求过程中发生的异常。

以下是一个自定义下载中间件的示例:

middlewares.py:

class CustomDownloaderMiddleware:
    def process_request(self, request, spider):
        # 在请求被发送之前修改请求头
        request.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
        return None

    def process_response(self, request, response, spider):
        # 在响应返回之前处理
        if response.status == 404:
            spider.logger.error('Page not found: %s', request.url)
        return response

    def process_exception(self, request, exception, spider):
        # 处理请求异常
        spider.logger.error('Request failed: %s', request.url)
        return None

🔧 中间件优先级别

中间件的优先级通过 DOWNLOADER_MIDDLEWARESSPIDER_MIDDLEWARES 设置。优先级较高的中间件会先处理请求或响应。例如:

settings.py:

DOWNLOADER_MIDDLEWARES = {
    'myproject.middlewares.CustomDownloaderMiddleware': 543,
}

🛠️ 自定义下载中间件

自定义下载中间件允许开发者实现特定的功能,例如修改请求头、处理重定向、设置代理等。以下是一个更复杂的自定义下载中间件示例:

middlewares.py:

class ProxyMiddleware:
    def process_request(self, request, spider):
        # 设置代理
        request.meta['proxy'] = 'http://myproxy:port'
        return None

    def process_response(self, request, response, spider):
        # 处理响应中的数据
        if response.status == 403:
            spider.logger.warning('Access denied: %s', request.url)
        return response

    def process_exception(self, request, exception, spider):
        # 处理请求异常
        spider.logger.error('Request exception: %s', exception)
        return None

settings.py 中启用自定义中间件:

DOWNLOADER_MIDDLEWARES = {
    'myproject.middlewares.ProxyMiddleware': 543,
}

📥 Scrapy 媒资下载器

Scrapy 媒资下载器用于处理图片、视频等媒体文件的下载。默认情况下,Scrapy 提供了一个 ImagesPipeline 用于下载和处理图片。以下是一个自定义的媒资下载器示例:

pipelines.py:

import scrapy
from scrapy.pipelines.images import ImagesPipeline

class MediaPipeline(ImagesPipeline):
    def get_media_requests(self, item, info):
        if 'image_urls' in item:
            for url in item['image_urls']:
                yield scrapy.Request(url)

    def file_path(self, request, response=None, info=None, *, item=None):
        return 'images/%s' % request.url.split('/')[-1]

settings.py 中启用媒体管道:

ITEM_PIPELINES = {
    'myproject.pipelines.MediaPipeline': 1,
}

📧 Scr

apy 邮件监听

Scrapy 允许通过扩展机制发送邮件通知。下面是一个示例,展示如何在爬虫结束后通过邮件发送通知:

extensions.py:

import smtplib
from scrapy import signals

class EmailNotificationExtension:
    def __init__(self, smtp_server, smtp_port, from_email, to_email, password):
        self.smtp_server = smtp_server
        self.smtp_port = smtp_port
        self.from_email = from_email
        self.to_email = to_email
        self.password = password

    @classmethod
    def from_crawler(cls, crawler):
        settings = crawler.settings
        return cls(
            smtp_server=settings.get('SMTP_SERVER'),
            smtp_port=settings.get('SMTP_PORT'),
            from_email=settings.get('FROM_EMAIL'),
            to_email=settings.get('TO_EMAIL'),
            password=settings.get('EMAIL_PASSWORD')
        )

    def open_spider(self, spider):
        self.spider = spider

    def close_spider(self, spider):
        self.send_email()

    def send_email(self):
        with smtplib.SMTP(self.smtp_server, self.smtp_port) as server:
            server.starttls()
            server.login(self.from_email, self.password)
            subject = 'Scrapy Spider Finished'
            body = 'Your Scrapy spider has finished running successfully!'
            msg = f'Subject: {subject}\n\n{body}'
            server.sendmail(self.from_email, self.to_email, msg)

settings.py 中启用邮件扩展:

EXTENSIONS = {
    'myproject.extensions.EmailNotificationExtension': 500,
}

以上内容详细解读了 Scrapy 框架的运行原理、底层源码、中间件和自定义功能,涵盖了从请求生成、响应处理到数据存储的完整流程。希望这些示例和讲解能够帮助你更好地理解和使用 Scrapy 框架,在实际开发中灵活应用。

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

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

相关文章

大模型书籍推荐:《大规模语言模型:从理论到实践》

书籍简介 在当前的人工智能领域,大规模语言模型(Large Language Models, LLMs)无疑是最重要的研究方向之一。它们不仅在自然语言处理方面取得了显著成果,还为其他领域带来了革命性的变化。《大规模语言模型:从理论到实…

维语驾考这款软件有人用过吗?靠谱吗?

维语驾考是专门为维吾尔语学车考驾照的学员而准备的驾考刷题软件。书写延续维语用法自右向左书写,可调节字号大小,支持维汉双语切换。2024驾考新规题库,内含科目一、科目四全真题库,每道题配备详细解析,帮助学员理解透…

Openwrt配置ZeroTier,实现公网访问内网中服务器

ZeroTier注册&Openwrt初始配置 首先来到Openwrt的VPN→ZeroTier页面,进行一个很简单的注册 注册后去zerotier的网页管理页面进行一个很简单的创建网络 复制网络ID备用 在openwrt填写网络ID并启用。如果你需要访问内网主机勾上 自动客户端NAT 在zerotier网络管理…

电子合同签署:2024年十佳选择与评估

文章将介绍10款电子合同签署平台:e签宝、上上签、合同宝、腾讯电子签、合易签、Zoho Sign、Nitro Sign、Secured Signing、Signeasy、Lightico。 在当今快速发展的商业环境中,选择一款合适的电子合同签署平台对于保证工作效率和合同执行的安全性至关重要…

精准洞察农田生态,智慧农业物联网环境监测与数据采集系统来袭

随着智慧农业的快速发展,利用物联网技术实现对农田种植状态的精准监测变得愈发重要。为了确保监测的准确性、一致性和有效性,规范农田物联网监测设备的技术参数、部署安装以及数据对接等技术指标势在必行。 本文技术说明旨在为相关设备的选择、安装和集…

深入源码P3C-PMD:rule (4)

系列文章目录 文章目录 系列文章目录rule 的应用类别 rule rule 自定义XML rule 定义Tree 漫游错误报告生命周期 designer rule相关的代码在每个子 module 的 rule 文件夹。而且也以一些 ruleset 为范围分了文件夹,如下图所示: 对每个 rule 来说&#xf…

Model Counting 2024 Public Instance Track 1 18000s(5h)测试结果

测试求解器:SharpSAT-TD与SharpSATTD-CH 18000s测试结果 测试结果图 对3600s未得到结果的数据进行18000s的测试,48组数据,最终有4组在18000s(5h)内解出 测试数据117 SharpSAT-TD输出: SharpSATTD-CH输出…

2024年底前,河南建筑装饰企业资质延期资料准备要点

针对2024年底前河南建筑装饰企业资质延期的资料准备要点,结合当前的政策要求和实际情况,以下是一些关键的准备要点: 一、了解政策与要求 政策关注: 密切关注河南省住房和城乡建设厅及地方建设主管部门发布的最新政策文件、通知公…

万字长文带你入门shell编程(超详细)

一、概述 Shell 是计算机操作系统中用户与操作系统内核之间的接口层,它提供了一种方式让用户能够通过命令行界面(CLI)与操作系统交互。Shell 可以被视为一个命令解释器,它接收用户输入的命令,解析这些命令&#xff0c…

趋动科技助力中国移动新型智算中心AI算力池化商用实践

由中国通信标准化协会、中国通信学会指导,CCSA TC610 SDN /NFV /AI标准与产业推进委员会主办的2024年云网智联大会于4月10日-11日在北京召开。 趋动科技联合申报的“中国移动新型智算中心AI算力池化商用实践”,获得2023年度SDN、NFV、网络AI优秀案例征集…

欧美农场小游戏 高端链游 休闲的欧美链游农场 【玫瑰庄园】 高端中英-欧美花园链游

#农场小游戏#链游【玫瑰庄园】 高端中英-欧美花园链游 玫瑰花园一、种子:种子分为五种:白玫瑰、红玫瑰、黑玫瑰、紫罗兰、郁金香。种子通过开启盲盒获得。二、种花:玩家开启盲盒获得的种子,会直接种下,种子种下后&…

深入浅出消息队列----【如何保证消息不重复?】

深入浅出消息队列----【如何保证消息不重复?】 消息一定会重复消息幂等消费改造业务符合天然幂等写法数据库唯一索引redis 唯一判断 本文仅是文章笔记,整理了原文章中重要的知识点、记录了个人的看法 文章来源:编程导航-鱼皮【yes哥深入浅出消…

从零开始的大模型训练教程

近年来,随着人工智能技术的迅猛发展,大模型(Large Models)成为了业界关注的焦点。这些模型,尤其是那些基于Transformer架构的自然语言处理模型,如GPT系列、BERT等,在各种任务上取得了前所未有的…

git add . 警告

这些警告是因为 Git 检测到你的文件使用了不同的换行符(LF 或 CRLF),并提示在下次 Git 操作中将会统一换行符为 CRLF。这通常发生在跨平台协作时,例如在 Windows 环境下编辑的文件可能使用 CRLF,而在类 Unix 环境&…

数据结构:基于顺序表实现通讯录系统(含源码)

目录 一、前言 二、各个功能的实现 2.1 初始化通讯录 2.2 添加通讯录数据 2.3 查找通讯录数据 2.4 删除通讯录数据 2.5 修改通讯录数据 2.6 展示通讯录数据​编辑 2.7 销毁通讯录数据 三、添加菜单和测试 四、完整源码 sxb.h sxb.c contact.h contact.c test.c 一、前…

ROS智能移动机器人实训

0.前言 1.任务 1.1.任务实训任务 1.使用/voice_aiui等语音服务完成基本的语音聊天(需唤醒词“元宝”)。 2.语音多点导航 3.语音单点导航 1.2.智能机器人仿真任务 1.3.智能机器人实物操作任务 2.目的 3.使用环境 4.综合项目实验 任务实训 问题 解决办法…

LinuxIO之文件系统的实现

Ext2/3/4 的layout文件系统的一致性: append一个文件的全流程掉电与文件系统的一致性fsck文件系统的日志ext4 mount选项文件系统的debug和dumpCopy On Write 文件系统: btrfs 预备知识:数据库里的transaction(事务)有什么特性? …

前端高薪岗位之大模型端上部署及训练

自2022年ChatGPT发布以来,以大模型为依托的AIGC相关的应用产品,比如ChatGPT、Midjourney、Stable Diffusion等,在社交网站的讨论热度持续攀升,引发了较大范围的好奇与关注。 目前,国内外各个科技大厂在大模型的端侧部…

手机k歌麦克风哪种好,口碑最好的k歌麦克风是哪款,麦克风推荐

​当我们谈论到演讲、表演或者录制视频时,一个高质量的无线麦克风能够使得整个体验提升至一个全新的水平。它不仅能够保证声音的清晰度和真实度,还能够让使用者在演讲或者表演时更加自信和舒适。基于对市场的深入研究和用户体验的考量,我挑选…