scrapy 爬虫中间件的学习

news2024/9/25 13:13:39

Scrapy中间件是一个处理Scrapy请求和响应的机制。中间件可以在请求或响应被Scrapy引擎处理之前或之后对其进行修改或操作,用于实现诸如缓存、代理、用户代理等功能。

Scrapy中间件的作用主要有以下几个方面:

1、对请求的处理:可以在请求被Scrapy引擎发送之前对其进行修改和处理,例如添加请求头、设置代理等。

2、对响应的处理:可以在响应到达Scrapy引擎之前对其进行修改和处理,例如解密响应、提取数据等。

3、对Spider的处理:可以对Spider的行为进行修改,例如在Spider的开始或结束时执行某些操作。

4、对引擎的处理:可以在Scrapy引擎处理请求和响应的过程中对其进行拦截和干预,例如实现反爬虫机制。

通过编写中间件,我们可以实现自己的定制功能,并且可以重复使用。

今天要学习的是:Scrapy框架中的download middlerware【下载中间件】用法。

一、官方文档中,对下载中间件的解释如下

下载中间件是介于scrapy的requests/response处理的钩子框架,是用于全局修改scrapy requests和response的一个轻量、底层的系统。

在这里插入图片描述

二、使用下载器中间件时必须激活这个中间件,方法是在settings.py文件中设置

DOWNLOADER_MIDDLEWARES这个字典,格式类似如下

DOWNLOADER_MIDDLEWARES = {
'scrapy_test.middlewares.ScrapyTestDownloaderMiddleware': 543,
}

数字越小,越靠近引擎,数字越大越靠近下载器,所以数字越小的,processrequest()优先处理;数字越大的,process_response()优先处理;
若需要关闭某个中间件直接设为None即可。由于中间件是按顺序运行的,因此如果遇到后一个中间件依赖前一个中间件的情况,中间件的顺序就至关重要如何确定后面的数字应该怎么写呢?
最简单的办法就是从543开始,逐渐加一,这样一般不会出现什么大问题。如果想把中间件做得更专业一点,那就需要知道Scrapy自带中间件的顺序,如图下图1.1所示。

在这里插入图片描述

三、中间件的理解

中间件本身是一个Python的类,只要爬虫每次访问网站之前都先“经过”这个类。在创建一个Scrapy工程以后,工程文件夹下会有一个middlewares.py文件,打开以后其内容如下图 2 所示。

在这里插入图片描述

Scrapy自动创建的这个中间件是一个爬虫中间件。而我们学习这些中间件的目的就是为了自己改写添加一些中间件。那么我们就需要看懂这些中间件做了什么。我们基本上是需要修改,代理中间件、UA中间件…
首先去看一下下载中间件信息如图3,这里中间件包含了请求头的设置、代理的设置、以及robot协议,那么单独去看一下这些默认信息。

在这里插入图片描述

四、那么这里便改写两个中间件,第一个是改写代理 IP、第二个是改写 UA、

一、由于当每个request通过下载中间件时,process_request(request,spider) 该方法被调用,直接看一下大佬理解的图片 5 如下:

在这里插入图片描述

4.1、第一个是改写代理 IP

4.1.1、修改代理 在middlewares.py中添加下面一段代码:

# 自己配置的都放在下面
class ProxyMiddleware(object):
    logger = logging.getLogger(__name__)

    def process_request(self, request, spider):
        self.logger.debug("using Proxy")
        request.meta['proxy'] = 'http://120.79.62.89:3128'  # 自己去免费的代理网站采集几个。
        return None

4.1.2、在settings文件中添加这段代码:

DOWNLOADER_MIDDLEWARES = {
    # 'scrapy_test.middlewares.ScrapyTestDownloaderMiddleware': 543,
    'scrapy_test.middlewares.ProxyMiddleware': 400,
    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': None,  # 这个是吧默认的default_setting文件中的给禁掉。
}

4.1.3、测试网站是:http://httpbin.org/get

4.1.4、spider代码

# -*- coding: utf-8 -*-
import scrapy


class HttpbinSpider(scrapy.Spider):
    name = 'httpbin'
    allowed_domains = ['httpbin.com']
    start_urls = ['http://httpbin.org/get']

    def parse(self, response):
        print(response.text)
        # print("此状态吗为:", response.status)

4.1.5、运行结果如下截图6所示:

在这里插入图片描述

4.2、开发UA中间件

4.2.1、当我们不改变代理的情况下可以看一下默认的代理是如下图 7:

在这里插入图片描述

开发UA中间件和开发代理中间件几乎一样,它也是从settings.py配置好的UA列表中随机选择一项,加入到请求头中。代码如下:

4.2.2、middlewares.py

import random
from scrapy_test.settings import USER_AGENT_LIST

class RandomUserAgentMiddleware(object):
    logger = logging.getLogger(__name__)

    def process_request(self, request, spider):
        rand_use = random.choice(USER_AGENT_LIST)
        if rand_use:
            self.logger.debug("using Random Headers")
            request.headers.setdefault('User-Agent', rand_use)

4.2.3、settings文件

DOWNLOADER_MIDDLEWARES = {
    # 'scrapy_test.middlewares.ScrapyTestDownloaderMiddleware': 543,
    'scrapy_test.middlewares.ProxyMiddleware': 400,
    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': None,
    # 添加这两项即可。
    'scrapy_test.middlewares.RandomUserAgentMiddleware': 400,
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
}

USER_AGENT_LIST = [
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36",
    "Dalvik/1.6.0 (Linux; U; Android 4.2.1; 2013022 MIUI/JHACNBL30.0)",
    "Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; HUAWEI MT7-TL00 Build/HuaweiMT7-TL00) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
    "AndroidDownloadManager",
    "Apache-HttpClient/UNAVAILABLE (java 1.4)",
    "Dalvik/1.6.0 (Linux; U; Android 4.3; SM-N7508V Build/JLS36C)",
    "Android50-AndroidPhone-8000-76-0-Statistics-wifi",
    "Dalvik/1.6.0 (Linux; U; Android 4.4.4; MI 3 MIUI/V7.2.1.0.KXCCNDA)",
    "Dalvik/1.6.0 (Linux; U; Android 4.4.2; Lenovo A3800-d Build/LenovoA3800-d)",
    "Lite 1.0 ( http://litesuits.com )",
    "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727)",
    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0",
    "Mozilla/5.0 (Linux; U; Android 4.1.1; zh-cn; HTC T528t Build/JRO03H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30; 360browser(securitypay,securityinstalled); 360(android,uppayplugin); 360 Aphone Browser (2.0.4)",
]

4.2.4、spider代码

# -*- coding: utf-8 -*-
import scrapy


class HttpbinSpider(scrapy.Spider):
    name = 'httpbin'
    allowed_domains = ['httpbin.com']
    start_urls = ['http://httpbin.org/get']

    def parse(self, response):
        print(response.text)
        # print("此状态吗为:", response.status)

4.2.5、结果如下图8所示

在这里插入图片描述

4.2.6、当然这是全局修改请求头,你也可以单独修改一个spiders的请求头,例如看源码

class Spider(object_ref):
    """Base class for scrapy spiders. All spiders must inherit from this
    class.
    """

    name = None
    custom_settings = None  # 这点就可以单独在每一个爬虫中修改。

    def __init__(self, name=None, **kwargs):
        if name is not None:
            self.name = name
        elif not getattr(self, 'name', None):
            raise ValueError("%s must have a name" % type(self).__name__)

4.2.6.1、那么修改spider的代码如下:

# -*- coding: utf-8 -*-
import scrapy


class HttpbinSpider(scrapy.Spider):
    name = 'httpbin'
    allowed_domains = ['httpbin.com']
    start_urls = ['http://httpbin.org/get']
    custom_settings = {
        "DEFAULT_REQUEST_HEADERS": {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
        }}

    def parse(self, response):
        print(response.text)
        # print("此状态吗为:", response.status)

4.2.6.2、看结果如下图 9 所示:

当然还有第三种、第四种方法如下:

修改settings文件如下:

# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'en',
    # 打开默认,覆盖掉 request headers,结果是相同的。
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
}

# Enable or disable spider middlewares
# See https://doc.scrapy.org/en/latest/topics/spider-middleware.html
# SPIDER_MIDDLEWARES = {
#    'scrapy_test.middlewares.ScrapyTestSpiderMiddleware': 543,
# }

# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
# DOWNLOADER_MIDDLEWARES = {
#     # 'scrapy_test.middlewares.ScrapyTestDownloaderMiddleware': 543,
#     'scrapy_test.middlewares.ProxyMiddleware': 400,
#     'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': None,
#     'scrapy_test.middlewares.RandomUserAgentMiddleware': 400,
#     'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
#
# }

结果和上图一样,这里就不展示了。

你以为就这么多方法,当然还有还是在settings文件找到如下代码:
# Crawl responsibly by identifying yourself (and your website) on the user-agent
# USER_AGENT = 'scrapy_test (+http://www.yourdomain.com)'    把这个打开并修改掉
例如改成:
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gec

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

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

相关文章

【Spark练习】RDD分区操作

练习1:行动(Action)操作算子方法 任务1: reduce // 1. 数组 val x sc.parallelize(List(1,2,3,4)) val y x.reduce( (a,b) > a b) // 2. 列表 val rdd sc.parallelize(List(1,2,3,4)) // 求和,将各个数累加,依次合并 下面两种方式相…

读书笔记// 《数据产品经理》

书名:写给数据产品经理新人的工作笔记 出版时间:2020年10月 本书以数据产品经理角色的定位和合作关系为切入点,站在整个数据体系的视角,从工作流程的角度剖析数据需求沟通和判断的过程、指标体系搭建的过程,同时介绍了…

Swift 中的 async/await ——代码实例详解

前言 async-await 是在 WWDC 2021 期间的 Swift 5.5 中的结构化并发变化的一部分。Swift 中的并发性意味着允许多段代码同时运行。这是一个非常简化的描述,但它应该让你知道 Swift 中的并发性对你的应用程序的性能是多么重要。有了新的 async 方法和 await 语句&am…

《人工智能概论》课程重点总结

目录 遗传算法相关参数问题 种群规模、迭代次数、交叉率、变异率对算法的影响 A*算法中open表和close表的作用 为什么A*算法中open表是增长的 启发式函数h(n)取值的影响 A*算法可以找到最优解的条件 模式识别系统的组成 有监督学习和无监督学习的区别 模型评估三大原则…

Baklib推荐:关于建设企业知识管理的有效方法

随着信息化和互联网技术的不断发展,企业面临着海量的信息和知识,如何有效地管理和利用这些信息和知识已经成为了企业发展的关键问题之一。企业知识管理是指企业利用信息技术手段,对企业内部的知识进行系统化、集成化、共享化管理,…

MPSOC(ZU9EG/ZU15EG)PCIE架构高性能数据预处理 FMC载板设计资料

板卡概述 PCIE707 是一款基于 PCIE 总线架构的高性能数据预处理 FMC载板,板卡具有 1 个 FMC(HPC)接口,1 路 PCIe x4 主机接口、 1 个 RJ45 千兆以太网口、2 个 QSFP 40G 光纤接口。板卡采用 Xilinx 的高性能 UltraScale MPSOC 系…

「蓝桥杯」积木大赛

积木大赛 题目描述 春春幼儿园举办了一年一度的"积木大赛"。今年比赛的内容是搭建一座宽度为 n 的大厦,大厦可以看成由 n 块宽度为 1 的积木组成,第 i 块积木的最终高度需要是 h_i 。 在搭建开始之前,没有任何积木(可…

Vue3中双向数据绑定与Pinia实践+JS数据引用的循环修改问题

Vue3 Pinia VUE3虽然出了很久了,但是很少深入研究,目前项目上遇到了一些问题,所以做个Note解决一下疑问: v-bind/v-model怎么与Pinia进行结合Object/Array数据大量处理时,为何有的修改不生效组合API与选项API选择 (…

赛道冠军为AI狂飙:实在智能即将重归福州,亮相第六届数字中国建设峰会

2023年4月26日至30日,第六届数字中国建设峰会将在福建省福州市举行。本届峰会以“加快数字中国建设,推进中国式现代化”为主题,由国家网信办、国家发展改革委、科技部、工业和信息化部、国务院国资委、福建省人民政府共同主办。 作为我国信息…

代码随想录算法训练营第二十五、二十七天 | 细节很多、树枝去重和树层去重的区分是难点、分割

216.组合总和III 文档讲解:代码随想录 (programmercarl.com) 视频讲解:和组合问题有啥区别?回溯算法如何剪枝?| LeetCode:216.组合总和III_哔哩哔哩_bilibili 状态:能做出来。和上一题没什么区别。思路直接…

SpringCloud微服务的熔断、限流、降级是怎么回事?

概述: 在开发公司商城项目时,由于采用的是微服务架构,每个模块之间使用OpenFeign组件进行通信,在遇到高并发时,为了保证系统的可用性和 可靠性,我们使用了阿里的Alibaba的Sentinel组件进行降级、限流和熔断…

vue2实现高德地图 JSAPI 2.0轨迹回放组件(MoveAnimation)

vue2实现高德地图 JSAPI 2.0轨迹回放组件(MoveAnimation) 声明: 本人是做java后端的,组件抽取不是很规范请大家见谅 前提: 需要注册高德开放平台,之后创建应用并且开通Web端(JS API)平台,然后拿到securityJsCode和key 实现效果: 1. 基础抽取 注意: 将securityJsCode和key修改为…

OpenGL(四)——纹理

目录 一、前言 二、纹理环绕方式 三、纹理过滤 3.1 邻近过滤 3.2 线性过滤 3.3 多级渐远纹理 四、加载、创建纹理 4.1 数据输入 4.2 生成并加载纹理 4.3 应用纹理坐标 4.4 顶点着色器配置纹理 4.5 片段着色器配置纹理 4.6 显示纹理 五、纹理单元 一、前言 为每个…

云原生技术概谈

云原生技术概谈 说起“云原生技术”,大家可能有点懵,只闻其声,不明其意。但是云原生背后典型的几个公司或者技术产品的名称可能大家经常听到: 比如容器技术的代表公司docker;容器编排技术开源产品kubernetes&#xff0…

推荐算法实战项目:DeepCross 原理以及案例实战(附完整 Python 代码)

本文要介绍的是由斯坦福大学联合Google的研究人员发表的论文《Deep & Cross Network for Ad Click Predictions》中提出的Deep&Cross模型,简称DCN。 DCN模型是Wide&Deep的改进版本,其中Deep部分的设计思路与Wide&Deep没有发生本质的变化…

计算机视觉的应用3-批量图片风格迁移之素描图片生成的应用

大家好,我是微学AI,今天给大家介绍一下计算机视觉的应用3-批量图片生成素描图片的应用,将一张图像转换为素描风格的图像的其实是模拟了人类视觉在观察物体时受到的光照条件。素描风格的图像在灰度值上表现出明暗交替的效果,这种效…

【干货】一文说透分布式一致性协议(下)

本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注"慕课网"! 作者:大能老师 | 慕课网讲师 前情提示:如需阅读“一文说透分布式一致性协议(上)”&#…

对多个点进行直线拟合操作

在图像处理中,通常会遇到根据给定的点集(比如轮廓)拟合出一条直线的情形。 import numpy as np import matplotlib.pyplot as plt import cv2def Cal_kb_linear_fitline(pointLocs):loc np.array(pointLocs) # loc 必须为矩阵形式&#xff…

二分类结局变量Logistic回归临床模型预测(二)——基线特征及三线表绘制(二)

本节讲的是二分类结局变量的临床模型预测,与之前讲的Cox回归不同,https://lijingxian19961016.blog.csdn.net/article/details/124088364https://lijingxian19961016.blog.csdn.net/article/details/124088364https://lijingxian19961016.blog.csdn.net/article/details/1300…

蓝牙耳机哪款性价比高一些?2023年性价比最高的蓝牙耳机推荐

随着科技的进步,蓝牙耳机已然成为我们生活中的一部分,无论是通勤、追剧、运动或者玩游戏,大都会用到蓝牙耳机。那么,哪款蓝牙耳机的性价比高一些?相信大多数人在选择产品的时候,都会看性价比。接下来&#…