爬虫:Scrapy热门爬虫框架介绍

news2024/11/24 13:49:24

专栏介绍

结合自身经验和内部资料总结的Python教程,每天3-5章,最短1个月就能全方位的完成Python的学习并进行实战开发,学完了定能成为大佬!加油吧!卷起来!

全部文章请访问专栏:《Python全栈教程(0基础)》
再推荐一下最近热更的:《大厂测试高频面试题详解》 该专栏对近年高频测试相关面试题做详细解答,结合自己多年工作经验,以及同行大佬指导总结出来的。旨在帮助测试、python方面的同学,顺利通过面试,拿到自己满意的offer!


文章目录

    • 专栏介绍
    • 爬虫框架Scrapy简介
      • Scrapy 概述
        • Scrapy的组件
        • 数据处理流程
      • 安装和使用Scrapy
        • 一个简单的例子


爬虫框架Scrapy简介

当你写了很多个爬虫程序之后,你会发现每次写爬虫程序时,都需要将页面获取、页面解析、爬虫调度、异常处理、反爬应对这些代码从头至尾实现一遍,这里面有很多工作其实都是简单乏味的重复劳动。那么,有没有什么办法可以提升我们编写爬虫代码的效率呢?答案是肯定的,那就是利用爬虫框架,而在所有的爬虫框架中,Scrapy 应该是最流行、最强大的框架。

Scrapy 概述

Scrapy 是基于 Python 的一个非常流行的网络爬虫框架,可以用来抓取 Web 站点并从页面中提取结构化的数据。下图展示了 Scrapy 的基本架构,其中包含了主要组件和系统的数据处理流程(图中带数字的红色箭头)。

Scrapy的组件

我们先来说说 Scrapy 中的组件。

  1. Scrapy 引擎(Engine):用来控制整个系统的数据处理流程。
  2. 调度器(Scheduler):调度器从引擎接受请求并排序列入队列,并在引擎发出请求后返还给它们。
  3. 下载器(Downloader):下载器的主要职责是抓取网页并将网页内容返还给蜘蛛(Spiders)。
  4. 蜘蛛程序(Spiders):蜘蛛是用户自定义的用来解析网页并抓取特定URL的类,每个蜘蛛都能处理一个域名或一组域名,简单的说就是用来定义特定网站的抓取和解析规则的模块。
  5. 数据管道(Item Pipeline):管道的主要责任是负责处理有蜘蛛从网页中抽取的数据条目,它的主要任务是清理、验证和存储数据。当页面被蜘蛛解析后,将被发送到数据管道,并经过几个特定的次序处理数据。每个数据管道组件都是一个 Python 类,它们获取了数据条目并执行对数据条目进行处理的方法,同时还需要确定是否需要在数据管道中继续执行下一步或是直接丢弃掉不处理。数据管道通常执行的任务有:清理 HTML 数据、验证解析到的数据(检查条目是否包含必要的字段)、检查是不是重复数据(如果重复就丢弃)、将解析到的数据存储到数据库(关系型数据库或 NoSQL 数据库)中。
  6. 中间件(Middlewares):中间件是介于引擎和其他组件之间的一个钩子框架,主要是为了提供自定义的代码来拓展 Scrapy 的功能,包括下载器中间件和蜘蛛中间件。

数据处理流程

Scrapy 的整个数据处理流程由引擎进行控制,通常的运转流程包括以下的步骤:

  1. 引擎询问蜘蛛需要处理哪个网站,并让蜘蛛将第一个需要处理的 URL 交给它。

  2. 引擎让调度器将需要处理的 URL 放在队列中。

  3. 引擎从调度那获取接下来进行爬取的页面。

  4. 调度将下一个爬取的 URL 返回给引擎,引擎将它通过下载中间件发送到下载器。

  5. 当网页被下载器下载完成以后,响应内容通过下载中间件被发送到引擎;如果下载失败了,引擎会通知调度器记录这个 URL,待会再重新下载。

  6. 引擎收到下载器的响应并将它通过蜘蛛中间件发送到蜘蛛进行处理。

  7. 蜘蛛处理响应并返回爬取到的数据条目,此外还要将需要跟进的新的 URL 发送给引擎。

  8. 引擎将抓取到的数据条目送入数据管道,把新的 URL 发送给调度器放入队列中。

上述操作中的第2步到第8步会一直重复直到调度器中没有需要请求的 URL,爬虫就停止工作。

安装和使用Scrapy

可以使用 Python 的包管理工具pip来安装 Scrapy。

pip install scrapy

在命令行中使用scrapy命令创建名为demo的项目。

scrapy startproject demo

项目的目录结构如下图所示。

demo
|____ demo
|________ spiders
|____________ __init__.py
|________ __init__.py
|________ items.py
|________ middlewares.py
|________ pipelines.py
|________ settings.py
|____ scrapy.cfg

切换到demo 目录,用下面的命令创建名为douban的蜘蛛程序。

scrapy genspider douban movie.douban.com

一个简单的例子

接下来,我们实现一个爬取豆瓣电影 Top250 电影标题、评分和金句的爬虫。

  1. items.pyItem类中定义字段,这些字段用来保存数据,方便后续的操作。

    import scrapy
    
    
    class DoubanItem(scrapy.Item):
       title = scrapy.Field()
       score = scrapy.Field()
       motto = scrapy.Field()
    
  2. 修改spiders文件夹中名为douban.py 的文件,它是蜘蛛程序的核心,需要我们添加解析页面的代码。在这里,我们可以通过对Response对象的解析,获取电影的信息,代码如下所示。

    import scrapy
    from scrapy import Selector, Request
    from scrapy.http import HtmlResponse
    
    from demo.items import MovieItem
    
    
    class DoubanSpider(scrapy.Spider):
       name = 'douban'
       allowed_domains = ['movie.douban.com']
       start_urls = ['https://movie.douban.com/top250?start=0&filter=']
    
       def parse(self, response: HtmlResponse):
           sel = Selector(response)
           movie_items = sel.css('#content > div > div.article > ol > li')
           for movie_sel in movie_items:
               item = MovieItem()
               item['title'] = movie_sel.css('.title::text').extract_first()
               item['score'] = movie_sel.css('.rating_num::text').extract_first()
               item['motto'] = movie_sel.css('.inq::text').extract_first()
               yield item
    

    通过上面的代码不难看出,我们可以使用 CSS 选择器进行页面解析。当然,如果你愿意也可以使用 XPath 或正则表达式进行页面解析,对应的方法分别是xpathre

    如果还要生成后续爬取的请求,我们可以用yield产出Request对象。Request对象有两个非常重要的属性,一个是url,它代表了要请求的地址;一个是callback,它代表了获得响应之后要执行的回调函数。我们可以将上面的代码稍作修改。

    import scrapy
    from scrapy import Selector, Request
    from scrapy.http import HtmlResponse
    
    from demo.items import MovieItem
    
    
    class DoubanSpider(scrapy.Spider):
       name = 'douban'
       allowed_domains = ['movie.douban.com']
       start_urls = ['https://movie.douban.com/top250?start=0&filter=']
    
       def parse(self, response: HtmlResponse):
           sel = Selector(response)
           movie_items = sel.css('#content > div > div.article > ol > li')
           for movie_sel in movie_items:
               item = MovieItem()
               item['title'] = movie_sel.css('.title::text').extract_first()
               item['score'] = movie_sel.css('.rating_num::text').extract_first()
               item['motto'] = movie_sel.css('.inq::text').extract_first()
               yield item
    
           hrefs = sel.css('#content > div > div.article > div.paginator > a::attr("href")')
           for href in hrefs:
               full_url = response.urljoin(href.extract())
               yield Request(url=full_url)
    

    到这里,我们已经可以通过下面的命令让爬虫运转起来。

    scrapy crawl movie
    

    可以在控制台看到爬取到的数据,如果想将这些数据保存到文件中,可以通过-o参数来指定文件名,Scrapy 支持我们将爬取到的数据导出成 JSON、CSV、XML 等格式。

    scrapy crawl moive -o result.json
    

    不知大家是否注意到,通过运行爬虫获得的 JSON 文件中有275条数据,那是因为首页被重复爬取了。要解决这个问题,可以对上面的代码稍作调整,不在parse方法中解析获取新页面的 URL,而是通过start_requests方法提前准备好待爬取页面的 URL,调整后的代码如下所示。

    import scrapy
    from scrapy import Selector, Request
    from scrapy.http import HtmlResponse
    
    from demo.items import MovieItem
    
    
    class DoubanSpider(scrapy.Spider):
       name = 'douban'
       allowed_domains = ['movie.douban.com']
    
       def start_requests(self):
           for page in range(10):
               yield Request(url=f'https://movie.douban.com/top250?start={page * 25}')
    
       def parse(self, response: HtmlResponse):
           sel = Selector(response)
           movie_items = sel.css('#content > div > div.article > ol > li')
           for movie_sel in movie_items:
               item = MovieItem()
               item['title'] = movie_sel.css('.title::text').extract_first()
               item['score'] = movie_sel.css('.rating_num::text').extract_first()
               item['motto'] = movie_sel.css('.inq::text').extract_first()
               yield item
    
  3. 如果希望完成爬虫数据的持久化,可以在数据管道中处理蜘蛛程序产生的Item对象。例如,我们可以通过前面讲到的openpyxl操作 Excel 文件,将数据写入 Excel 文件中,代码如下所示。

    import openpyxl
    
    from demo.items import MovieItem
    
    
    class MovieItemPipeline:
    
       def __init__(self):
           self.wb = openpyxl.Workbook()
           self.sheet = self.wb.active
           self.sheet.title = 'Top250'
           self.sheet.append(('名称', '评分', '名言'))
    
       def process_item(self, item: MovieItem, spider):
           self.sheet.append((item['title'], item['score'], item['motto']))
           return item
    
       def close_spider(self, spider):
           self.wb.save('豆瓣电影数据.xlsx')
    

    上面的process_itemclose_spider都是回调方法(钩子函数), 简单的说就是 Scrapy 框架会自动去调用的方法。当蜘蛛程序产生一个Item对象交给引擎时,引擎会将该Item对象交给数据管道,这时我们配置好的数据管道的parse_item方法就会被执行,所以我们可以在该方法中获取数据并完成数据的持久化操作。另一个方法close_spider是在爬虫结束运行前会自动执行的方法,在上面的代码中,我们在这个地方进行了保存 Excel 文件的操作,相信这段代码大家是很容易读懂的。

    总而言之,数据管道可以帮助我们完成以下操作:

    • 清理 HTML 数据,验证爬取的数据。
    • 丢弃重复的不必要的内容。
    • 将爬取的结果进行持久化操作。
  4. 修改settings.py文件对项目进行配置,主要需要修改以下几个配置。

    # 用户浏览器
    USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
    
    # 并发请求数量 
    CONCURRENT_REQUESTS = 4
    
    # 下载延迟
    DOWNLOAD_DELAY = 3
    # 随机化下载延迟
    RANDOMIZE_DOWNLOAD_DELAY = True
    
    # 是否遵守爬虫协议
    ROBOTSTXT_OBEY = True
    
    # 配置数据管道
    ITEM_PIPELINES = {
      'demo.pipelines.MovieItemPipeline': 300,
    }
    

    说明:上面配置文件中的ITEM_PIPELINES选项是一个字典,可以配置多个处理数据的管道,后面的数字代表了执行的优先级,数字小的先执行。

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

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

相关文章

ROS之rviz显示GNSS/INS运动轨迹

目录 一、显示自定义圆形轨迹 二、显示GNSS/INS轨迹 2.1代码show_path.cpp 2.2CMakeLists.txt 2.3显示效果 一、显示自定义圆形轨迹 参考:(九)ROS在rviz中实时显示轨迹(nav_msgs/Path消息的使用)_nav_msgs/path.…

Java:正则表达式案例:爬数据,重复数据替换,数据分割

使用正则表达式查找一段文本中的内容 需求:请把下面文本中的电话,邮箱,座机号码,热线都爬取出来。 String data "电话:1866668888,18699997777\n" "或者联系邮箱: boniuitcast.cn,\n" "座机…

使用 PostgreSQL 创建全文搜索引擎1

PostgreSQL 提供了必要的模块,可以组合和创建自己的全文搜索搜索引擎。让我们尝试一下。 这是系列文章的第 1 部分,将要在其中探索 PostgreSQL 中的全文搜索功能,并研究我们可以完成多少典型的搜索引擎功能。在第 2 部分中,我们将…

【Redis从头学-0】一张思维导图对Redis做出基本介绍

🧑‍💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 📖所属专栏:Re…

[centos]设置主机名

1、设置 hostnamectl set-hostname 名字 2、查看是否生效 hostnamectl status 3、打开一个新链接就可以了

零代码编程:用ChatGPT批量删除Excel文件中的行

文件夹中有上百个Excel文件,每个文件中都有如下所示的两行,要进行批量删除。 在ChatGPT中输入提示词: 你是一个Python编程专家,要完成一个处理Excel文件内容的任务,具体步骤如下: 打开F盘的文件夹&#x…

16.1.2 Linux 的多用户多任务环境

在 Linux 下面执行一个指令时,系统会将相关的权限、属性、程序码与数据等均载入内存, 并给予这个单元一个程序识别码 (PID),最终该指令可以进行的任务则与这个 PID 的权限有关。根据这个说明,我们就可以简单…

ESD培训和咨询的相关服务

ESD(Electrostatic Discharge,静电放电)是指在两个物体之间发生的电荷平衡或不平衡,导致静电能量的释放。静电放电可能会对敏感的电子设备、芯片和电子元件产生损坏,因此对于需要处理电子设备的行业来说,ES…

MSP432自主开发笔记6:定时器多通道捕获多条编码器线脉冲数

所用开发板:MSP432P401R 今日在此更新一下编码器测速的定时器捕获写法,之前学习时竟然忘记更新了~~ 本文讲如何用定时器的通道来 捕获编码器的脉冲信号数量,不提供速度路程的计算方式, 文章提供源码,测试工程下载&a…

手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】之实现任务阶段 5- bean 后置处理器

😀前言 手动实现 Spring 底层机制【初始化 IOC容器依赖注入BeanPostProcessor 机制AOP】的第五篇具体实现了任务阶段 5- bean 后置处理器 🏠个人主页:尘觉主页 🧑个人简介:大家好,我是尘觉,希…

ModaHub魔搭社区:从OpenAI实践看分工必要性,核心关注工作流相关的基础软件工具栈

从OpenAI实践看分工必要性,核心关注工作流相关的基础软件工具栈 参考海外OpenAI的率先尝试,工作流分工、点工具加持助力成功。一方面,OpenAI在《GPT-4 Technical Report》论文中[1]中披露了参与GPT 4开发的人员分工,共249人,角色分工明确,预训练、强化学习和对齐、部署等…

时间序列去趋势化和傅里叶变换

在计算傅里叶变换之前对信号去趋势是一种常见的做法,特别是在处理时间序列时。在这篇文章中,我将从数学和视觉上展示信号去趋势是如何影响傅里叶变换的。 这篇文章的目的是让介绍理解什么是常数和线性去趋势,为什么我们使用它们,…

CRM系统如何搭建?流程是什么样的?

CRM系统可以提高企业的销售效率和客户满意度,从而增加企业的收入和利润。但是,要想成功地上线CRM系统,需要经过一系列的步骤和流程,下面说说,企业如何上线CRM系统?CRM系统搭建流程。 1、需求分析 需求分析…

记一次物理机安装centos7遇到的问题

首先制作U盘镜像(之前装windows的大白菜之类的就没用了) 用的这个UltraISO制作U盘镜像 然后从U盘启动开始安装, 问题一 安装时报错 dracut-pre-udev[351]:modprobe :ERROR:could not insert ‘floppy’ dracut-pre-udev[351]:modprobe…

Nacos源码 (3) 注册中心

本文将从一个服务注册示例入手,通过阅读客户端、服务端源码,分析服务注册、服务发现原理。 使用的2.0.2的版本。 返回目录 客户端 创建NacosNamingService对象 NacosNamingService nacosNamingService new NacosNamingService(NACOS_HOST);NacosNami…

华为OD机试 - 最长的连续子序列 (Java 2022Q4 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷)》…

ISIS技术(第三十七课)

1 分享一下华为官网上的一张地图 官网地址:https://support.huawei.com/hedex/hdx.do?docid=EDOC1000105967&id=ZH-CN_CONCEPT_0000001501534705 2 路由的分类 -直连路由 直接连接的路由,且配置了IP地址之后(在同一网段内),就是直连路由。 -非直连路由 -静态路由…

如何在金属制品业运用IPD?

金属制品行业是指以金属材料为原料,通过加工、制造、加工等工艺制造出各种金属制品的企业和产业。这些金属制品包括但不限于机械设备、工具、建筑材料、家具、电子产品、交通运输设备等。金属制品加工业是机械装备行业的一个子行业,包括结构性金属制品制…

SpringBoot对一个URL通过method(GET、POST、PUT、DELETE)实现增删改查操作

目录 1. rest风格基础2. 开启方法3. 实战练习 1. rest风格基础 我们都知道GET、POST、PUT、DELETE分别对应查、增、改、删除 虽然Postman这些工具可以直接发送GET、POST、PUT、DELETE请求。但是RequestMapping并不支持PUT和DELETE请求操作。需要我们手动开启 2. 开启方法 P…

ModaHub魔搭社区:Milvus Cloud素材集合帖,等你查收

Hi~Milvus Cloud 的各位朋友,这是一期 Milvus Cloud 素材弹药库的集中汇总帖。随着向量数据库的火爆,越来越多的伙伴开始关注到向量数据库并开始使用 Milvus Cloud 。 考虑到目前信息获取的渠道多且分散,我们专门为大家整理了一期 Milvus Cloud 信息集合帖,让大家可以在快…