Scrapy

发布于:2024-04-25 ⋅ 阅读:(24) ⋅ 点赞:(0)

【 一 】Scrapy介绍

【0】前言

Scrapy知识预备

​ 爬虫毕竟是在网页里面抓取数据的,因此前端那些东西没学过也要稍微懂点。HTML、CSS简单的语法,Xpath、正则表达式等等,需要有一些简单的基础。

​ Scrapy一个开源和协作的框架,其最初是为了页面抓取(更确切来说,网络抓取)所设计的,使用它可以快速、简单、可扩展的方式从网站中提取所需要的数据。但目前Scrapy的用途十分广泛,可用与如数据挖掘、监测和自动化测试等领域,也可以应用在获取API所返回的数据(如: Amazon Associatates web services)或者统一的网络爬虫。

Scrapy就是爬虫界的django

【 1 】开源和协作的框架

  • 其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,
  • 使用它可以以快速、简单、可扩展的方式从网站中提取所需的数据。
  • 但目前Scrapy的用途十分广泛,可用于如数据挖掘、监测和自动化测试等领域,也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。
  • Scrapy 是基于twisted框架开发而来,twisted是一个流行的事件驱动的python网络框架。
  • 因此Scrapy使用了一种非阻塞(又名异步)的代码来实现并发。
  • Scrapy框架类似于Django框架

(摘自Scrapy官方文档:docs.scrapy.org/en/latest/i…

  • https://docs.scrapy.org/en/latest/topics/architecture.htm

【 2 】Scrapy的基本介绍

【1】组件介绍

  • Scrapy Engine(引擎) : 负责Spider、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等。
  • Scheduler(调度器) : 它负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。
  • Downloader(下载器) :负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理,
  • Spider(爬虫) :它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器).
  • Item Pipeline(管道) :它负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方。
  • Downloader Middlewares(下载中间件) :你可以当作是一个可以自定义扩展下载功能的组件。
  • Spider Middlewares(Spider中间件) :你可以理解为是一个可以自定扩展和操作引擎和Spider中间通信的功能组件(比如进入Spider的Responses;和从Spider出去的Requests)
组件 作用
Scrapy Engine 引擎,处理整个框架的数据流
Scheduler 调度器,接收引擎发过来的请求,将其排至队列中,当引擎再次请求时返回
Downloader 下载器,下载所有引擎发送的请求,并将获取的源代码返回给引擎,之后由引擎交给爬虫处理
Spiders 爬虫,接收并处理所有引擎发送过来的源代码,从中分析并提取item字段所需要的数据,并将需要跟进的url提交给引擎,再次进入调度器
Item Pipeline 管道,负责处理从爬虫中获取的Item,并进行后期处理
Downloader Middlewares 下载中间件,可以理解为自定义扩展下载功能的组件
Spider Middlewares Spider中间件,自定义扩展和操作引擎与爬虫之间通信的功能组件

【2】数据流控制

image-20240403134110943 在Scrapy中,数据流由执行引擎控制,流程如下:

  1. 引擎从Spider获取要爬取的初始请求。
  2. 引擎将请求安排到调度器中,并请求下一个要爬取的请求。
  3. 调度器将下一个要爬取的请求返回给引擎。
  4. 引擎将请求发送给下载器,经过下载器中间件。
  5. 页面下载完成后,下载器生成一个带有该页面的响应,并将其发送给引擎,此过程会经过下载器中间件。
  6. 引擎从下载器接收响应,并将其经过Spider中间件发送给Spider进行处理。
  7. Spider处理响应,经过Spider中间件返回抓取的数据项和新的请求。
  8. 引擎将处理后的数据项发送到数据管道,然后将处理后的请求发送给调度器,并请求下一个要爬取的请求。
  9. 重复上述过程(从步骤3)直到调度器没有更多的请求为止。
其流程可以描述如下:
  1. 调度器把requests–>引擎–>下载中间件—>下载器
  2. 下载器发送请求,获取响应---->下载中间件---->引擎—>爬虫中间件—>爬虫
  3. 爬虫提取url地址,组装成request对象---->爬虫中间件—>引擎—>调度器
  4. 爬虫提取数据—>引擎—>管道
  5. 管道进行数据的处理和保存

【 3 】小结

  1. scrapy的概念:Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架

  2. scrapy框架的运行流程以及数据传递过程:

  3. 调度器把requests–>引擎–>下载中间件—>下载器

  4. 下载器发送请求,获取响应---->下载中间件---->引擎—>爬虫中间件—>爬虫

  5. 爬虫提取url地址,组装成request对象---->爬虫中间件—>引擎—>调度器

  6. 爬虫提取数据—>引擎—>管道

  7. 管道进行数据的处理和保存

  8. scrapy框架的作用:通过少量代码实现快速抓取

  9. 掌握scrapy中每个模块的作用:
    引擎(engine):负责数据和信号在不同模块间的传递 调度器(scheduler):实现一个队列,存放引擎发过来的request请求对象
    下载器(downloader):发送引擎发过来的request请求,获取响应,并将响应交给引擎
    爬虫(spider):处理引擎发过来的response,提取数据,提取url,并交给引擎
    管道(pipeline):处理引擎传递过来的数据,比如存储
    下载中间件(downloader middleware):可以自定义的下载扩展,比如设置代理ip
    爬虫中间件(spider middleware):可以自定义request请求和进行response过滤

  10. 理解异步和非阻塞的区别:异步是过程,非阻塞是状态

【 二 】Scrapy框架的基本使用

【1】查看帮助

scrapy -h
scrapy <command> -h
  • 第一个命令用于查看全部可用命令的帮助信息
  • 第二个命令用于查看特定命令的帮助信息

【2】全局命令和项目命令

  • Project-only必须切到项目文件夹下才能执行
  • Global的命令则不需要
Global commands:
startproject #创建项目
genspider    #创建爬虫程序
settings     #如果是在项目目录下,则得到的是该项目的配置
runspider    #运行一个独立的python文件,不必创建项目
shell        #scrapy shell url地址  在交互式调试,如选择器规则正确与否
fetch        #独立于程单纯地爬取一个页面,可以拿到请求头
view         #下载完毕后直接弹出浏览器,以此可以分辨出哪些数据是ajax请求
version      #scrapy version 查看scrapy的版本,scrapy version -v查看scrapy依赖库的版本
Project-only commands:
crawl        #运行爬虫,必须创建项目才行,确保配置文件中ROBOTSTXT_OBEY = False
check        #检测项目中有无语法错误
list         #列出项目中所包含的爬虫名
parse        #scrapy parse url地址 --callback 回调函数  #以此可以验证我们的回调函数是否正确
bench        #scrapy bentch压力测试

【1】全局命令(Global commands)

  • startproject:创建一个新的 Scrapy 项目。
  • genspider:创建一个新的爬虫程序。
  • settings:显示一个 Scrapy 项目的配置信息。
  • runspider:运行一个独立的 Python 文件作为爬虫,不需要创建项目。
  • shell:进入 Scrapy 的交互式调试环境,可以检查选择器规则是否正确。
  • fetch:单独请求一个页面,并获取响应结果。
  • view:下载指定页面并在浏览器中打开,用于检查通过哪些请求获取数据。
  • version:查看当前安装的 Scrapy 版本号。

【2】项目命令(Project-only commands)

  • crawl:运行一个 Scrapy 爬虫,必须在项目目录下执行且确保配置文件中的 ROBOTSTXT_OBEY 设置为 False
  • check:检查项目中是否存在语法错误。
  • list:列出项目中包含的所有爬虫名称。
  • parse:使用回调函数解析给定的 URL,用于验证回调函数是否正确。
  • bench:用于对 Scrapy 进行压力测试。

【 3 】创建Scrapy项目

  • 新建项目 (scrapy startproject xxx):新建一个新的爬虫项目**

【1】创建工程

scrapy startproject one

image-20240403142922892

image-20240403143119152

image-20240403143241248

【2】查看文件目录结构

  • 在Windows系统中,你可以使用tree命令来显示当前目录及其子目录中的文件结构:

    # tree /F
    
  • 在类Unix/Linux系统中,你可以使用tree命令来显示当前目录及其子目录中的文件结构,但需要先安装tree工具。如果没有安装,你可以使用ls命令来显示当前目录中的文件和目录:

    # ls -R
    

image-20240403144142803

文件 作用
scrapy.cfg 配置文件
spiders 存放你Spider文件,也就是你爬取的py文件
items.py 相当于一个容器,和字典较像
middlewares.py 定义Downloader Middlewares(下载器中间件)和Spider Middlewares(蜘蛛中间件)的实现
pipelines.py 定义Item Pipeline的实现,实现数据的清洗,储存,验证。
settings.py 全局配置
  • scrapy.cfg
    • 项目的主配置信息,用来部署scrapy时使用,爬虫相关的配置信息在settings.py文件中。
  • items.py
    • 设置数据存储模板,用于结构化数据
    • 如:Django的Model
  • pipelines
    • 数据处理行为
    • 如:一般结构化的数据持久化
  • settings.py
    • 配置文件
    • 如:递归的层数、并发数,延迟下载等。强调:配置文件的选项必须大写否则视为无效,正确写法USER_AGENT=‘xxxx’
  • spiders
    • 爬虫目录
    • 如:创建文件,编写爬虫规则

【 3 】创建爬虫

​ 要在Scrapy中创建一个爬虫,你可以使用以下命令:

# scrapy genspider <spider_name> <start_url>

​ 其中,<spider_name>是你要创建的爬虫的名称,<start_url>是你要开始爬取的起始URL。

scrapy genspider 命令创建一个新的爬虫时,你需要提供两个参数:

# scrapy genspider example http://example.com

# scrapy genspider jing http://www.baidu.com  
  1. 爬虫文件的名字(可以是任何你喜欢的名字)。
  2. 要爬取的网站的起始URL

image-20240403145302379

【4】简单测试

import scrapy


class JingSpider(scrapy.Spider):
    # 爬虫文件的唯一标识
    name = "jing"
    # 允许访问的域名
    allowed_domains = ["www.baidu.com"]
    # 起始 的 URL 列表 (重要)
    # 列表内部的 url 都会被框架进行异步请求发送
    start_urls = ["http://www.baidu.com"]

    # 数据解析主函数:自动调用
    # 调用的次数取决于 start_urls 列表内元素的个数
    def parse(self, response):
        # response : 表示的就是响应对象
        print("response:::", response.text)

【5】启动项目

  • 通过指定的命令启动 Scrapy 项目,而非通过文件启动
scrapy crawl jing

【6】优化启动

【1】降低日期等级
  • settings.py 文件中添加指定配置项
# 指定输出日志的类型:
LOG_LEVEL = 'ERROR'

image-20240403150130201

【2】不遵循ROBOTS协议
ROBOTSTXT_OBEY = False
【3】以启动文件启动项目
  • 每一次终端启动和麻烦,我们可以在项目根目录下新建启动文件
  • bin.py:
from scrapy.cmdline import execute


execute(['scrapy', 'crawl', '自定义爬虫文件名', "--nolog"])

【 三 】Scrapy框架之数据解析

【1】项目执行流程简解

  • 启动爬虫:
    • 开始执行爬虫程序。
  • 创建Request对象:
    • 将start_urls地址包装成request对象,其中包含待爬取的网页链接、回调函数等信息。
  • 交给引擎:
    • 将创建好的request对象交给引擎进行处理。
  • 调度器排队:
    • 引擎将请求交给调度器,调度器按照一定的策略(如先进先出)将请求放入队列中进行排队。
  • 引擎处理:
    • 引擎从调度器中取出请求,并选择合适的下载中间件进行处理。
  • 下载器处理:
    • 下载器根据请求中的链接发起网络请求,下载相应的页面内容,并将下载结果返回给引擎。
  • 下载完成:
    • 下载器将网页内容下载完成后,将下载结果返回给引擎。
  • 引擎传递给爬虫:
    • 引擎将下载结果传递给相应的爬虫解析函数(例如parse函数)进行处理。
  • 爬虫解析:
    • 爬虫解析函数对下载下来的网页内容进行解析,提取出需要的数据,并生成新的Request对象或是Item对象。
  • 回到步骤2:
    • 解析函数可以继续生成新的Request对象,或是处理Item对象
    • 然后回到步骤2,继续执行后续的请求和解析过程。

【2】Xpath解析器

【1】概览

  • Scrapy xpath语法,Xpath是XML Path的简介,基于XML树状结构,可以在整个树中寻找锁定目标节点。由于HTML文档本身就是一个标准的XML页面,因此我们可以使用XPath的语法来定位页面元素。

【2】路径表达式

表达式 描述 实例
nodename 选取nodename节点的所有子节点 //div
/ 从根节点选取 /div
// 选取任意位置的节点,不考虑他们的位置 //div
. 选取当前节点 ./div
选取当前节点的父节点
@ 选取属性 //@calss
  • 示例
语法 说明
artical 选取所有artical元素的子节点
/artical 选取根元素artical
./artical 选取当前元素下的artical
…/artical 选取父元素下的artical
artical/a 选取所有属于artical的子元素a元素
//div 选取所有div 子元素,无论div在任何地方
artical//div 选取所有属于artical的div 元素,无论div元素在artical的任何位置
//@class 选取所有class属性
a/@href 选取a标签的href属性
a/text() 选取a标签下的文本
string(.) 解析出当前节点下所有文字
string(…) 解析出父节点下所有文字

【3】谓语

  • 谓语被嵌在方括号内,用来查找某个特定的节点或包含某个制定的值的节点
语法 说明
/artical/div[1] 选取所有属于artical 子元素的第一个div元素
/artical/div[last()] 选取所有属于artical子元素的最后一个div元素
/artical/div[last()-1] 选取所有属于artical子元素的倒数第2个div元素
/artical/div[position()❤️] 选取所有属于artical子元素的前2个div元素
//div[@class] 选取所有拥有属性为class的div节点
//div[@class=”main”] 选取所有div下class属性为main的div节点
//div[price>3.5] 选取所有div下元素值price大于3.5的div节点