【爬虫】4.1 Scrapy 框架爬虫简介

news2024/11/28 7:46:20

目录

1. Scrapy 框架介绍

2. 建立 Scrapy 项目

3. 入口函数与入口地址

4. Python 的 yield 语句

5. Scrapy 爬虫的数据类型


1. Scrapy 框架介绍

1.1 Scrapy 的安装

pip install scrapy -i https://pypi.tuna.tsinghua.edu.cn/simple/

1.2 Scrapy爬虫框架结构

“5+2”结构,9数据流、3路径、2出入口 

5+2结构(5个功能模块+2个中间件)


9个数据流


数据流的3个路径

       


路径1 :① ②

①Engine从Spider处获得爬取请求(Request)。

②Engine将爬取请求转发给Scheduler,用于调度。

路径2:③④⑤⑥

③Engine从Scheduler处获得下一个要爬取的请求。

④Engine将爬取请求通过中间件发送给Downloader 爬取网页后。

⑤Downloader形成响应(Response) 通过中间件发给Engine。

⑥Engine将收到的响应通过中间件发送给Spider处理。

路径3:⑦⑧⑨

⑦ Spider处理响应后产生爬取项(scraped Item) 和新的爬取请求(Requests)给Engine。 ⑧ Engine将爬取项发送给Item Pipeline(框架出口)。

⑨ Engine将爬取请求发送给Scheduler。


数据流的出入口(2)

Engine控制各模块数据流,不间断从Scheduler处获得爬取请求,直至请求为空 。

框架入口:Spider(初始爬取请求)

框架出口:Item Pipeline(爬取结果及处理)


解析5+2结构

 Engine

(1) 控制所有模块之间的数据流

(2) 根据条件触发事件

不需要用户修改

Downloader

根据请求下载网页

不需要用户修改

Scheduler

对所有爬取请求进行调度管理      

不需要用户修改

Spiders

(1) 解析Downloader返回的响应(Response)

(2) 产生爬取项(scraped item)

(3) 产生额外的爬取请求(Request)

需要用户编写配置代码

Item Pipelines

(1) 以流水线方式处理Spider产生的爬取项

(2) 由一组操作顺序组成,类似流水线,每个操 作是一个Item Pipeline类型

(3) 可能操作包括:清理、检验和查重爬取项中 的HTML数据、将数据存储到数据库。

需要用户编写配置代码

Downloader Middleware

目的:实施Engine、Scheduler和Downloader 之间进行用户可配置的控制

功能:修改、丢弃、新增请求 或 响应

用户可以编写配置代码

Spider Middleware

目的:对请求和爬取项的再处理

功能:修改、丢弃、新增请求或爬取项

用户可以编写配置代码


1.3 命令行的使用

Scrapy命令行格式:

>scrapy <command> [options] [args]

Scrapy常用命令
命令说明格式
startproject创建一个新工程scrapy startproject <name> [dir]
genspider创建一个爬虫scrapy genspider [options] <name> <domain>
settings获得爬虫配置信息scrapy settings [options]
crawl运行一个爬虫scrapy crawl <spider>
list列出工程中所有爬虫scrapy list
shell启动URL调试命令行scrapy shell [url]

为什么Scrapy采用命令行创建和运行爬虫?

命令行(不是图形界面)更容易自动化,适合脚本控制。

本质上,Scrapy是给程序员用的,功能(而不是界面)更重要。

比较爬虫技术路线Scrapy与 Requests
RequestsScrapy
相同点

1. 实现Python爬虫重要技术路线

2. 可用性都好,文档丰富,入门简单

3.两者都没有处理js、提交表单、应对验证码等功能(可扩展)

不同点页面级爬虫网站级爬虫
功能库框架
并发性考虑不足,性能较差并发性好,性能较高
重点在于页面下载重点在于爬虫结构
定制灵活一般定制灵活,深度定制困难
上手十分简单入门稍难

选用哪个技术路线开发爬虫呢?

  • 非常小的需求,requests库
  • 不太小的需求,Scrapy框架
  • 定制程度很高的需求(不考虑规模),自搭框架,requests > Scrapy

2. 建立 Scrapy 项目

(1)进入命令行窗体,在D盘中 建立一个文件夹例如example, 进入D:\example然后执行命令:

scrapy startproject Test

该命令建立一个名称为 Test的scrapy项目,如下图所示

(2)Scrapy项目建立后会在D:\example中建立Test文件夹,同时下面还有另外一个Test子文件夹,如下图所示(将这个项目移到4_1 Scrapy 框架爬虫简介下,用PyCharm打开)

  •  example
    • Test
      • Test
        • spiders (Spiders代码模板目录(继承类))
          • __init__.py (初始文件,无需修改)
        • __init__.py (初始化脚本)
        • items.py (Items代码模板(继承类))
        • middlewares.py (Middlewares代码模板(继承类))
        • pipelines.py (Pipelines代码模板(继承类))
        • settings.py (Scrapy爬虫的配置文件)
      • scrapy.cfg (服务器部署Scrapy爬虫的配置文件)          

 (3)为了测试的这个scrapy项目,首先先建立一个Web网站, 可以在./example中建立一个 server.py程序:

import flask

app = flask.Flask(__name__)


@app.route("/")
def index():
    return "测试 scrapy"


if __name__ == "__main__":
    app.run()

 这个程序建立好就可以执行了,建立 http://127.0.0.1:5000 的网站,访问这个网站返回 “测试 scrapy”。

(4)在 example\Test\Test\spider文件夹中 建立一个自己的 python文件,例如MySpider.py,这个程序就是爬虫程序

爬虫程序MySpider.py如下:

import scrapy


class MySpider(scrapy.Spider):
    name = "mySpider"

    def start_requests(self):
        url = 'http://127.0.0.1:5000'
        yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response, **kwargs):
        print(response.url)
        data = response.body.decode()
        print(data)

(5)在 example\Test\Test文件夹中建立一个

执行程序run.py如下:

from scrapy import cmdline
cmdline.execute("scrapy crawl mySpider -s LOG_ENABLED=False".split())

(6)保存这些程序并启动server.py, 然后允许run.py, 结果如下:


 代码解读

MySpider.py

(1) 

import scrapy
引入scrapy程序包,这个包中有一个请求对象Request与一个响应对象 Response类。 

(2)

class MySpider(scrapy.Spider):
    name = "mySpider"
任何一个爬虫程序类都继承于scrapy.Spider类,任何一个爬虫程序都 有一个名字,这个名字在整个爬虫项目中是唯一的,我们这个爬虫 名字为"mySpider"。

(3) 

def start_requests(self):
    url = 'http://127.0.0.1:5000'
    yield scrapy.Request(url=url, callback=self.parse)
   这个地址url是爬虫程序的入口地址,这个start_requests函数是程序的入口函数。程序开始时确定要爬取的网站地址,然后建立一个scrapy.Request请求类,向这个类提供url参数,指明要爬取的网页地址。爬取网页完成后就执行默认的回调函数parse。 
   值得指出的是scrapy的执行过程是异步进行的,即指定一个url网址开始爬取数据时, 程序不用一直等待这个网站的响应,如果网站迟迟不响应,那么整个程序不是卡死 !scrapy提供一个回调函数机制,爬取网站时同时提供一个回调函数, 当网站响应后就触发执行这个回调函数,网站什么时候响应就什么时候调用这个回调函数,这样对于响应时间很长的网站也不怕了。
    yield后面介绍

(4)

def parse(self, response, **kwargs):
    print(response.url)
    data = response.body.decode()
    print(data)
   回调函数parse包含一个scrapy.Response类的对象response,响应的一切信息,其中response.url是网站的网址,response.body是网站响应的二进制数据,即网页的内容。通过decode()解码后变成字符串,就可以print出来了。

        到目前为止爬虫程序就编写好了,但是这个程序MySpider.py只是一个 类,不能单独执行,要执行这个爬虫程序必须使用scrapy中专门的命令scrapy crawl。在命令行窗体,D:\example\Test\dTest中 执行命令:

scrapy crawl mySpider -s LOG_ENABLED=False

        那么就可以看到执行的结果如下图所示,其中mySpider就是我们爬虫程序的名称,后面的参数是不显示调试信息。

        但是这样需要我们从PyCharm与命令行窗体之间来回切换,为了简单起见,专门设计一个Python程序run.py,它包含执行命 令行的语句:

from scrapy import cmdline
cmdline.execute("scrapy crawl mySpider -s LOG_ENABLED=False".split())

        直接运行run.py就可以执行MySpider.py的爬虫程序了,效果与命令行窗体中执行相同,结果还直接显示在 PyCharm中。

3. 入口函数与入口地址

程序中使用了入口函数:

def start_requests(self):
    url = 'http://127.0.0.1:5000'
    yield scrapy.Request(url=url, callback=self.parse)

实际上这个函数也可以用start_urls的入口地址来代替:

start_urls = ['http://127.0.0.1:5000']

        入口函数可以有多个,因此start_urls 是一个列表。入口函数与入口地址的作用一样,都是引导函数的开始。

4. Python 的 yield 语句

在入口函数中有一条yield语句,yield是一个Python的一种特殊语句,

主要作用:返回一个值等待被取走

def fun():
    s = ['a', 'b', 'c']
    for x in s:
        yield x
    print("fun End")


f = fun()
print(f)  # <generator object fun at 0x000001CD628A7740>
for e in f:
    print(e)

程序执行结果:

由此可见,fun返回一个 generator 的对象 ,这种对象包含一系列的元素,可以使用 for 循环提取,执行循环的过程如下:

for e in f:
    print(e)

        第一次  for e in f 循环,f 执行到 yield 语句,就返回一个值 'a', for 循环从 f 抽取的元素是 'a', 然后 e='a' 打印a。fun 中执行到了yield 时会等待 yield 返回的值被抽走,同时 fun 停留在yield 语句,一旦被抽走,再次循环,yield 返回 'b'。直到循环结束。

        只要包含 yield 语句的函数都返回一个 generator 的可循环对象,执行到 yield 语句只返回一个值,等待调用循环抽取,一旦调用抽取后,函数又继续进行。这个过程非常类似两个线程的协作过程,当提供数据的一方准备好数据把 yield 提交数据时,就等待另外一方把数据抽取走,如果不抽走,yield 就一直等待, 一旦抽走后,数据提供方继续它的程序,一直等到出现下一处 yield 或者程序结束。

        Scrapy 的框架使用的是异步执行的过程,因此大量使用 yield 语句。


yield <==>生成器

包含yield语句的函数是一个生成器

生成器每次产生一个值(yield语句),函数被冻结,被唤醒后再产生一个值 生成器是一个不断产生值的函数

return 与 yield 的区别

def gen(n):
    for i in range(n):
        yield i ** 2


for i in gen(5):
    print(i, end="  ")  # 0  1  4  9  16  
print()


# ==========================================
def square(n):
    ls = [i ** 2 for i in range(n)]
    return ls


for i in square(5):
    print(i, end="  ")  # 0  1  4  9  16  
print()

yield 生成器的优势

  • 更节省存储空间
  • 响应更迅速
  • 使用更灵活

5. Scrapy 爬虫的数据类型

Request 类

class scrapy.http.Request()

Request对象表示一个HTTP请求由Spider生成,由Downloader执行

属性或方法说明
.urlRequest对应的请求URL地址
.method对应的请求方法,'GET' 'POST'等
.headers字典类型风格的请求头
.body请求内容主体,字符串类型
.meta用户添加的扩展信息,在Scrapy内部模块间传递信息使用
.copy()复制该请求

Response 类

class scrapy.http.Response()

Response对象表示一个HTTP响应由Downloader生成,由Spider处理

属性或方法说明
.urlResponse对应的URL地址
.statusHTTP状态码,默认是200
.headersResponse对应的头部信息
.bodyResponse对应的内容信息,字符串类型
.flags一组标记
.request产生Response类型对应的Request对象
.copy()复制该响应

Item 类

class scrapy.item.Item()

Item对象表示一个从HTML页面中提取的信息内容 由Spider生成,由Item Pipeline处理,Item 类似字典类型,可以按照字典类型操作

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

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

相关文章

「HTML和CSS入门指南」table 标签详解

什么是 table 标签? 在 HTML 中,table 标签用于创建表格。使用 table 标签可以帮助您以可视化和结构化的方式呈现数据。 table 标签的基本语法 以下是 table 标签的基本语法: <table><tr><th>姓名</th><th>年龄</th><th>性别&l…

chatgpt赋能python:Python如何辨别非数字符号

Python如何辨别非数字符号 在进行数据处理或者字符串操作时&#xff0c;经常会遇到需要识别和处理非数字符号的情况&#xff0c;如何在Python中进行辨别呢&#xff1f; 什么是非数字符号 非数字符号是指数字以外的字符&#xff0c;包括但不限于以下类型&#xff1a; 字母&a…

Drools 规则引擎原理

目录 Drools规则引擎基本定义介绍优劣优点缺点 基本概念规则引擎构成 规则结构规则引擎执行过程规则存储Kie 介绍Kie 相关组件知识库规则引擎与知识库Drools 存储规则的数据结构 Rete 算法原理优缺点优点缺点 举例 前向和后向链推理机制前向链后向链对比 应用场景概念和特点架构…

MMPretrain

title: mmpretrain实战 date: 2023-06-07 16:04:01 tags: [image classification,mmlab] mmpretrain实战 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ccTl9bOl-1686129437336)(null)] 主要讲解了安装,还有使用教程.安装教程直接参考官网.下面讲…

【mmpose】从openmmlab官方文档看mmpose架构设计,模块组成,快速上手实现关键点检测效果(动物,人体,手部等)

MMPOSE 架构设计 MMPose 1.0 与之前的版本有较大改动&#xff0c;对部分模块进行了重新设计和组织&#xff0c;降低代码冗余度&#xff0c;提升运行效率&#xff0c;降低学习难度。使用 MMPose 1.0 时开发者会关心的内容&#xff1a; 整体代码架构与设计逻辑&#xff1b; 如何…

告别加班!9款Figma汉化插件助你高效工作,提升生产力!

Figma是一款极受设计师欢迎的设计工具&#xff0c;而Figma中文版即时设计则是在Figma基础上改进而来&#xff0c;有着众多的Figma汉化插件&#xff0c;可以加速设计工作&#xff0c;让每位设计师完成更好的创作。 打开即时设计官网首页&#xff0c;点击【设计社区】-【插件广场…

虚函数表详解及其应用场景

目录 概述1. 虚函数表概述2. 虚函数表的实现原理2.1. 虚函数的声明和定义2.2. 虚函数表的创建和初始化2.3. 虚函数调用的过程 3. 虚函数表的应用场景3.1. 多态性3.2. 基类指针和引用的使用3.3. 动态绑定3.4. 接口定义 结论 概述 在面向对象编程中&#xff0c;虚函数表&#xf…

java-JDBC

java-JDBC 1. JDBC概念 JDBC 就是使用Java语言操作关系型数据库的一套API 全称&#xff1a;( Java DataBase Connectivity ) Java 数据库连接 sun公司就指定了一套标准接口&#xff08;JDBC&#xff09;&#xff0c;JDBC中定义了所有操作关系型数据库的规则。 我们需要使用接口…

人群聚集监测预警算法 python

人群聚集监测预警系统采用pythonopencv网络模型AI视频智能分析技术&#xff0c;人群聚集监测预警算法对人员聚集情况进行实时监测&#xff0c;当人群聚集过于密集时&#xff0c;系统将自动发出警报。OpenCV基于C实现&#xff0c;同时提供python, Ruby, Matlab等语言的接口。Ope…

R语言 tidyverse系列学习笔记(系列1)

tidyverse 译 “洁净的宇宙” > “极乐净土” 以 iris 鸢尾花数据集为例 ** 查看数据集** ** 查看维度dimention** dim(iris)iris 数据集有150个对象&#xff08;observation&#xff09;&#xff0c;5列 ( Sepal.Length , Sepal.Width , Petal.Length , Petal.Width , S…

阿里服务器配置服务器自启动

一开始 是在 /etc/rc.local 文件中添加的如下脚本 bash /mnt/cangjie-server/action.sh start bash /usr/local/nginx/sbin/nginx pm2 start npm--name"cangjieWeb"run start 启动服务器&#xff0c;服务并没有执行。 后面把执行脚本的 bash 指令去掉 如下&#xf…

Linux内核中断和Linux内核定时器

目录 Linux内核中断 Linux内核定时器 Linux内核中断 int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev) 功能&#xff1a;注册中断 参数&#xff1a; irq : 软中断号 gpio的软中断号 软中断号 gpio_to_i…

期末复习样卷

期末复习样卷 目录 期末复习样卷选择题简答题1. 画E-R图并将其转换为适当的关系模型2. 规范化模式分解——教学关系&#xff08;学号&#xff0c;姓名&#xff0c;年龄&#xff0c;性别&#xff0c;系别&#xff0c;系主任&#xff0c;课程名&#xff0c;成绩&#xff09;3.关系…

重装Windows系统

1.前言 有的时候&#xff0c;面对杂乱的文件系统&#xff0c;整理是十分困难的…… 有的时候&#xff0c;下载软件的时候会附带上某一些病毒、木马…… 有的时候&#xff0c;不满于更新后的系统…… 这些种种都可以使用重装系统解决&#xff0c;接下来我来带您学习重装windows…

煤炭价格学习

大佬发表时间在2022.11.17 神华月线&#xff0c;因为没有送配股&#xff0c;所以肯定是除权看的&#xff08;前复权看的不要跟我谈技术&#xff0c;因为你不配&#xff09; 除权&#xff0c;前复权&#xff0c;后复权 理解这三者区别之前&#xff0c;首先我们要简单了解 除权和…

【String字符串之后续】

我们继续上一篇文章为大家讲解&#xff0c;String字符串的相关知识&#xff0c;希望大家有所收获&#x1f49e;&#x1f49e;&#x1f49e; 字符串前篇的链接: link 目录 1.字符串的替换2.字符串的拆分3.字符串截取4.去掉空格5.String的不可变性6. 字符串的修改7.StringBuilde…

STL:string类使用

编码&#xff1a; ASCII unicode–utf-8 utf-16----一个字符2个字符 utf-32----一个字符4个字节 gbk–中文编码表 string&#xff1a; 是一个特殊的容器&#xff0c;对数据&#xff08;字符数组&#xff09;和库函数&#xff08;strlen等&#xff09;进行封装 STL提供的内容…

OpenStack部署(三)

OpenStack部署 6. Neutron6.1 创建Neutron数据库并授权6.2 获得admin凭证6.3 创建 neutron 用户并设置密码6.4 添加admin角色到neutron 用户6.5 创建neutron服务实体6.6 创建网络服务API端点6.7 安装并配置neutron服务6.8 链接plugin.ini文件6.9 初始化neutron数据库6.10 重启计…

连续两年!PingCAP 入选 Gartner 云数据库“客户之声”,获评“卓越表现者”最高分

近日&#xff0c;全球权威信息技术研究与咨询机构 Gartner 发布了云数据库市场领域 2023 Gartner Peer Insights™“Voice of the Customer” 报告&#xff0c;PingCAP 在报告中获得的客户总体评分达到 4.9 分&#xff08;满分 5 分&#xff09;&#xff0c;在所有入选企业中位…

CBCGPCaptionBar 使用实例说明

CBCGPCaptionBar的位置如下&#xff1a; 如图区域就是 MainFrame.h中声明&#xff1a; CBCGPCaptionBar m_wndCaptionBar; MainFrame.cpp中创建显示控件&#xff1a; BOOL CMainFrame::CreateCaptionBar () { if (!m_wndCaptionBar.Create (WS_CHILD | WS_V…