深入剖析Python的爬虫框架Scrapy的结构与运作流程

yizhihongxing

深入剖析Python的爬虫框架Scrapy的结构与运作流程

Scrapy的结构

Scrapy是一个基于Python语言并采用了Twisted异步网络框架的开源爬虫框架,其整个架构由以下组件构成:

  • 引擎(Engine):控制各个组件之间的信号传递和流转。
  • 调度器(Scheduler):管理爬取请求的队列,并通过引擎将请求发送给爬虫。
  • 下载器(Downloader):下载网络上的数据并将其返回给引擎。
  • 爬虫(Spider):解析网页并提取数据,将提取到的数据返回给引擎。
  • 项目管道(Pipeline):对爬到的数据进行处理,包括储存、去重等操作。
  • 下载器中间件(Downloader Middleware):对请求和响应进行处理,比如设置代理、修改请求头等。
  • 爬虫中间件(Spider Middleware):对爬虫的请求和响应进行处理,比如过滤器、添加请求头等。

Scrapy的运作流程

Scrapy的具体运作流程如下:

  1. 引擎(Engine)接收到起始URL,并使用调度器(Scheduler)将其放入待爬队列中。
  2. 引擎从待爬队列中取出下一个URL,并生成对应的请求(Request),通过下载器中间件(Downloader Middleware)进行请求处理。
  3. 下载器(Downloader)将网络上的数据下载下来,并将其作为响应(Response)返回给引擎。
  4. 引擎将响应(Response)发送给爬虫(Spider)进行处理。
  5. 爬虫通过解析响应(Response)提取目标数据,并生成新的请求(Request)放入待爬队列中。
  6. 重复2~5步骤,直到待爬队列为空。

下面通过两个示例来详细说明Scrapy的整个运作流程。

示例一:爬取《三体》小说

我们首先需要在Scrapy项目根目录下通过命令 scrapy startproject sanwen 创建一个名为“sanwen”的项目。然后运行以下命令:

cd sanwen
scrapy genspider sanwen_spider sanwen.com

这个命令会在项目的spiders目录下新建一个名为“sanwen_spider”的spider。

我们进入到spiders目录,找到sanwen_spider.py进行编辑:

import scrapy

class SanwenSpiderSpider(scrapy.Spider):
    name = 'sanwen_spider'
    allowed_domains = ['sanwen.com']
    start_urls = ['https://www.sanwen.com/book/']

    def parse(self, response):
        # 获取对应小说的链接
        urls = response.css(".allbook .bt > a::attr(href)").getall()
        # 逐个解析小说目录
        for url in urls:
            yield response.follow(url, callback=self.parse_chapter)

    def parse_chapter(self, response):
        # 获取小说章节链接
        urls = response.css(".listbox2_dir a::attr(href)").getall()
        # 逐个解析小说章节内容
        for url in urls:
            yield response.follow(url, callback=self.parse_content)

    def parse_content(self, response):
        # 将小说正文全部提取并存储到文件
        title = response.css(".title > h1::text").get()
        content = response.css(".article_content").get()
        with open(f"{title}.html", "w", encoding="utf-8") as f:
            f.write(content)

我们通过产生三个级联请求的方式,将小说的每章内容提取下来并存储到本地文件中。具体流程如下:

  1. 引擎(Engine)将起始URL https://www.sanwen.com/book/ 交给调度器(Scheduler)。
  2. 调度器(Scheduler)通过下载器中间件(Downloader Middleware)将其发送给下载器(Downloader)。
  3. 下载器(Downloader)向网站 https://www.sanwen.com/book/ 发送请求(request),并下载对应的响应(response)。
  4. 引擎(Engine)将响应(response)交给sanwen_spider进行处理。
  5. sanwen_spider通过response.follow()方法访问每个小说详细页面,从页面中获取小说章节链接每章内容。
  6. 引擎会将小说章节链接和回调函数callback将两者打包成一个请求(Request)并交给调度器。
  7. 调度器将请求(Request)加入队列。
  8. 重复6~7步,直到队列为空。

这样,Scrapy的整个流程就完整地完成了。

示例二:使用CrawlSpider自动爬取网站上的电影信息

除了Spider之外,Scrapy还提供了另外一个Spark Type - CrawlSpider,该Spider是一个可以自动化爬取网站全站信息的爬虫。

下面我们以爬取IMDB网站上所有电影信息为例,演示如何使用CrawlSpider自动化爬取。首先我们需要在Scrapy项目根目录下通过命令 scrapy startproject imdbcrawl 创建一个名为“imdbcrawl”的项目。然后运行以下命令:

cd imdbcrawl
scrapy genspider -t crawl imdbcrawl_spider imdb.com

这个命令会在项目的spiders目录下新建一个名为“imdbcrawl_spider”的CrawlSpider。

我们进入到spiders目录,找到imdbcrawl_spider.py进行编辑:

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from imdbcrawl.items import ImdbcrawlItem

class ImdbcrawlSpiderSpider(CrawlSpider):
    name = 'imdbcrawl_spider'
    allowed_domains = ['imdb.com']
    start_urls = ['https://www.imdb.com/chart/top']

    rules = (
        Rule(LinkExtractor(restrict_xpaths="//td[@class='titleColumn']/a"), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        item = ImdbcrawlItem()
        # 获取电影信息
        item['title'] = response.css("div.title_wrapper h1::text").get().strip()
        item['release_year'] = response.css("#titleYear a::text").get()
        item['rating'] = response.css("span.ratingValue span::text").get()
        yield item

我们通过定义rules及其回调函数parse_item(),CrawlSpider会自动抓取所有电影的网页并执行parse_item()函数,将相关的信息提取出来。

这个项目的Item定义及其管道实现有点麻烦,但有点偏离Scrapy框架本身的范畴,在这里我们就不展开说明了,这里只是向大家演示CrawlSpider是如何运作的。

  1. 引擎(Engine)将起始URL https://www.imdb.com/chart/top 交给调度器(Scheduler)。
  2. 调度器(Scheduler)通过下载器中间件(Downloader Middleware)将其发送给下载器(Downloader)。
  3. 下载器(Downloader)向网站 https://www.imdb.com/chart/top 发送请求(request),并下载对应的响应(response)。
  4. 引擎(Engine)将响应(response)交给imdbcrawl_spider进行处理。
  5. imdbcrawl_spider分析响应(response),并通过规则(Rules)提取电影信息,生成新的请求(Requests),并加入Request的队列,并交给调度器(Scheduler)进行调度。
  6. 调度器(Scheduler)分析从imdbcrawl_spider回调函数中产生的requests,并将其加入Request队列,等待下一次下载器(Downloader)执行。
  7. 重复2~6步,直到队列为空。

这样,我们使用CrawlSpider完全自动化地完成了对IMDB电影网站的爬取。

以上就是Scrapy框架的整体结构和运行流程,通过以上两个示例我们了解了如何使用Scrapy爬取数据。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入剖析Python的爬虫框架Scrapy的结构与运作流程 - Python技术站

(0)
上一篇 2023年5月14日
下一篇 2023年5月14日

相关文章

  • 详解Python编程中对Monkey Patch猴子补丁开发方式的运用

    详解Python编程中对Monkey Patch猴子补丁开发方式的运用 什么是猴子补丁 猴子补丁(Monkey Patching)是指在运行时动态修改一个类或模块的行为,可以加入、删除或修改属性和方法。在Python中,猴子补丁可以用来修改第三方库中的函数或方法,或者动态增加自己的代码,实现一些特定的用途。 猴子补丁的实现方式 猴子补丁的实现方式有多种,最简…

    python 2023年6月3日
    00
  • Python使用一行代码获取上个月是几月

    要用一行代码获取上个月的月份,可以使用Python的datetime模块。下面是完整的攻略: 导入datetime模块 首先,需要导入datetime模块,这个模块包含了日期和时间相关的类和方法。 import datetime 获取当前日期和时间 假设当前时间是2022年3月15日,可以使用datetime模块的datetime.now()方法获取当前的日…

    python 2023年6月2日
    00
  • Python多线程、异步+多进程爬虫实现代码

    下面是Python多线程、异步+多进程爬虫实现代码的完整攻略。 一、什么是多线程、异步和多进程 在开始讲解Python多线程、异步+多进程爬虫实现代码之前,我们先来了解一下多线程、异步和多进程的概念。 1. 多线程 多线程是指在一个程序中同时执行多个不同的线程,每个线程处理不同的任务。多线程可以提高程序的运行效率,减少响应时间,提高用户体验。 2. 异步 异…

    python 2023年5月14日
    00
  • 10个Python常用的损失函数及代码实现分享

    10个Python常用的损失函数及代码实现分享 在机器学习中,损失函数是用于衡量模型预测结果与真实结果之间差异的函数。在Python中,有许多常的损失函数,下面是10个Python常用的损失及代码实现分享: 1. 均方误差(Mean Squared Error) 均误差是最常用的损失函数之一,它衡模型预测结果与真实结果之间的平均差异。均方误差越小,表示模型的…

    python 2023年5月13日
    00
  • 一个可以套路别人的python小程序实例代码

    针对“一个可以套路别人的python小程序实例代码”的完整攻略,我将按照以下步骤来讲解: 需求分析:确定小程序的功能和实现要求 编写伪代码:根据需求分析,编写伪代码 编写代码:根据伪代码,编写实际代码 测试和调试:对代码进行测试和调试,确保程序运行正常 下面我将详细讲解每个步骤的内容。 1. 需求分析 在进行编码前,首先需要确定小程序的功能和实现要求。根据该…

    python 2023年5月23日
    00
  • 用Python写脚本,实现完全备份和增量备份的示例

    让我们来详细讲解如何用Python写脚本实现完全备份和增量备份。 1. 准备工作 在编写Python备份脚本之前,我们需要安装必要的第三方库:pymysql和pymongo(如果你的脚本需要备份MySQL或MongoDB)。使用pip可以很方便地安装它们: pip install pymysql pymongo 2. 完全备份示例 以下是一个示例,它演示如何…

    python 2023年6月2日
    00
  • Python中TypeError:unhashable type:’dict’错误的解决办法

    当我们在使用Python进行开发时,有时候会遇到 “TypeError:unhashabletype:’dict’” 错误,这个错误一般是由于我们将一个字典作为某些操作函数的输入参数,并将这个字典作为空间的 key 进行 hash 计算导致的。下面我将为大家介绍解决这个错误的方法。 1. 错误原因 在 Python 中,一般而言我们需要将某些函数的输入数据进…

    python 2023年5月13日
    00
  • python爬虫scrapy框架之增量式爬虫的示例代码

    针对这个主题,我可以提供一份针对“python爬虫scrapy框架之增量式爬虫的示例代码”的完整攻略。 什么是增量式爬虫? 在介绍示例代码之前,我们先来了解一下什么是“增量式爬虫”。简单来说,增量式爬虫就是针对已经抓取过的内容进行增量的、增量的更新;只爬取新加入的,而不是全盘的重新抓取。对于时间线较为敏感的数据应用,增量式爬虫可以减少开销,提高数据更新速度。…

    python 2023年5月14日
    00
合作推广
合作推广
分享本页
返回顶部