scrapy中间件详解

scrapy中间件介绍

=

=
scrapy中间件是scrapy框架的重要组成部分
分为两大种类:下载器中间件(DownloaderMiddleware)和爬虫中间件(SpiderMiddleware
图中4、5为下载器中间件
图中6、7为爬虫中间件

在这里插入图片描述

下载器中间件是Scrapy请求/响应处理的钩子框架。这是一个轻,低层次的系统,全球范围内改变斯拉皮的请求和响应。

下载器中间件主要功能:
1、添加ip代理
2、添加cookie
3、添加UA
4、请求重试

Spider中间件是一个钩子框架,可以钩住Scrapy的Spider处理机制,在该机制中,您可以插入自定义功能来处理发送到的响应。 蜘蛛 用于处理和处理由spider生成的请求和项目。

爬虫中间件主要功能:
1、处理引擎传递给爬虫的响应
2、处理爬虫传递给引擎的请求
3、处理爬虫传递给引擎的数据项

其中,爬虫中间件在以下情况中会被调用:

1.当运行到 yield scrapy.Request()或者 yield item 的时候,爬虫中间件的
2.process_spider_output()方法被调用。 当爬虫本身的代码出现了 Exception 的时候,爬虫中间件的
3.process_spider_exception()方法被调用。 当爬虫里面的某一个回调函数 parse_xxx()被调用之前,爬虫中间件的
4. process_spider_input()方法被调用。 当运行到 start_requests()的时候,爬虫中间件的
5. process_start_requests()方法被调用。

=

=
首先,先创建一个spider用于学习middleware
打开其中的middlewares.py
初始化样子:

# Define here the models for your spider middleware
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/spider-middleware.html

from scrapy import signals

# useful for handling different item types with a single interface
from itemadapter import is_item, ItemAdapter


class MiddlewareproSpiderMiddleware:
    # Not all methods need to be defined. If a method is not defined,
    # scrapy acts as if the spider middleware does not modify the
    # passed objects.

    @classmethod
    def from_crawler(cls, crawler):
        # This method is used by Scrapy to create your spiders.
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_spider_input(self, response, spider):
        # Called for each response that goes through the spider
        # middleware and into the spider.

        # Should return None or raise an exception.
        return None

    def process_spider_output(self, response, result, spider):
        # Called with the results returned from the Spider, after
        # it has processed the response.

        # Must return an iterable of Request, or item objects.
        for i in result:
            yield i

    def process_spider_exception(self, response, exception, spider):
        # Called when a spider or process_spider_input() method
        # (from other spider middleware) raises an exception.

        # Should return either None or an iterable of Request or item objects.
        pass

    def process_start_requests(self, start_requests, spider):
        # Called with the start requests of the spider, and works
        # similarly to the process_spider_output() method, except
        # that it doesn’t have a response associated.

        # Must return only requests (not items).
        for r in start_requests:
            yield r

    def spider_opened(self, spider):
        spider.logger.info('Spider opened: %s' % spider.name)


class MiddlewareproDownloaderMiddleware:
    # Not all methods need to be defined. If a method is not defined,
    # scrapy acts as if the downloader middleware does not modify the
    # passed objects.

    @classmethod
    def from_crawler(cls, crawler):
        # This method is used by Scrapy to create your spiders.
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_request(self, request, spider):
        # Called for each request that goes through the downloader
        # middleware.

        # Must either:
        # - return None: continue processing this request
        # - or return a Response object
        # - or return a Request object
        # - or raise IgnoreRequest: process_exception() methods of
        #   installed downloader middleware will be called
        return None

    def process_response(self, request, response, spider):
        # Called with the response returned from the downloader.

        # Must either;
        # - return a Response object
        # - return a Request object
        # - or raise IgnoreRequest
        return response

    def process_exception(self, request, exception, spider):
        # Called when a download handler or a process_request()
        # (from other downloader middleware) raises an exception.

        # Must either:
        # - return None: continue processing this exception
        # - return a Response object: stops process_exception() chain
        # - return a Request object: stops process_exception() chain
        pass

    def spider_opened(self, spider):
        spider.logger.info('Spider opened: %s' % spider.name)

可以看到分为两类:

class MiddlewareproDownloaderMiddleware:
class MiddlewareproSpiderMiddleware:

以下依次介绍

=

=

=

下载器中间件

添加ip代理

测试ip地址可访问网站 http://httpbin.org/ip
方法一:
不用中间件。重写start_ requests方法,在发送请求时传入ip—proxy

yield scrapy.Request(self.start_urls[0], meta={"proxy": proxy})

方法二:
使用中间件。

第一种:静态ip中间件
test:

import scrapy


class MiddlewaretestSpider(scrapy.Spider):
    name = 'middlewareTest'
    # allowed_domains = ['http://httpbin.org/ip']
    start_urls = ['http://httpbin.org/ip']

    def parse(self, response):
        print('IP地址--> ', response.text)

在middlewares中重写编写一个类:

class TestProxyMiddleware(object):
    def process_request(self, request, spider):
        proxy = "http://113.57.26.117"
        request.meta["proxy"] = proxy

在settings中打开;

DOWNLOADER_MIDDLEWARES = {
   # 'middlewarePro.middlewares.MiddlewareproDownloaderMiddleware': 543,
    'middlewarePro.middlewares.TestProxyMiddleware':543,

}

结果:

IP地址-->  {
  "origin": "113.57.26.117"
}


第二种:动态ip
动态ip的创建和静态ip创建原理相似,只是每次给request的meta赋予不同的proxy参数,这就要依靠代理池俩实现。
代理池就是有很多ip组成的字典,每次随机抽取一个ip,如果这个代理池足够大,就可以降低重复的概率
test不变
middlewares:
先导入两个类:

import random
from scrapy.utils.project import get_project_settings
class TestProxyMiddleware(object):

    def __init__(self):

        self.settings = get_project_settings()

    def process_request(self, request, spider):

        proxy = random.choice(self.settings['PROXIES'])
        request.meta["proxy"] = proxy

settings中接入一个代理池:

PROXIES = [
    'http://114.217.243.25:8118',
    'http://125.37.175.233:8118',
    'http://1.85.116.218:8118'
]

=

=

UA中间件

UA中间件的设置和代理的设置基本相同
middlewares中新建一个类UAMiddleware

class UAMiddleware(object):
 
    def process_request(self, request, spider):
        ua = random.choice(settings['USER_AGENT_LIST'])
        request.headers['User-Agent'] = ua

在settings中添加一个含UA数据的字典即可。

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)",
]

记得在settings中开启该通道;

DOWNLOADER_MIDDLEWARES = {
   # 'middlewarePro.middlewares.MiddlewareproDownloaderMiddleware': 543,
    'middlewarePro.middlewares.TestProxyMiddleware':543,
	'middlewarePro.middlewares.UAMiddleware' : 544,
}

=

=

cookies中间件

cookies值主要用于爬取一些需要登录的网站,保持登录状态。
设置cookies中间件首先要有若干cookies值,获取cookies可以用selenium登录要爬取的网址,然后下载cookies,多重复几遍就可得到多个cookies值

具体操作和上述类似

=

=

爬虫中间件

Spider middleware主要有三个作用:
1、在downloader生成request发送给spider之前,对request进行处理
2、在spider生成request发送给scheduler之前,对request进行处理
3、在spider生成request发送给item pipeline之前,对item进行处理

核心方法
# 返回None或一个异常。
#如果是None,就继续调用其他的spider middleware。
#如果是一个异常,调用request里的errback()方法,再抛出异常是交给process_spider_exception(response, exception, spider)处理
process_ spider _input(response, spider)

# 必须返回一个包括request或item对象的可迭代对象
process_spider_output(response, result, spider)

# 返回None 或 
# 一个包括request或item对象的可迭代对象
process_spider_exception(response, exception, spider)

#返回一个request对象的可迭代对象
process_start_requests(start_requests, spider)

上述只需要其中一个方法就可以定义一个spider middleware。

  • 3
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Scrapy是一个Python爬虫框架,它提供了一种快速、高效、可扩展的方式来爬取网站数据。Scrapy的主要特点包括: 1. 基于Twisted异步网络框架,可以高效地处理大量的并发请求。 2. 支持多种数据格式,包括XML、JSON、CSV等。 3. 提供了强大的数据提取功能,可以通过XPath或CSS选择器来提取网页中的数据。 4. 支持分布式爬取,可以通过Scrapy-Redis等插件实现。 5. 提供了丰富的中间件和扩展机制,可以方便地定制爬虫行为。 Scrapy的使用流程一般包括以下几个步骤: 1. 定义Item:定义需要爬取的数据结构。 2. 编写Spider:编写爬虫代码,定义如何爬取网站数据。 3. 定义Pipeline:定义数据处理流程,对爬取到的数据进行处理和存储。 4. 配置Settings:配置爬虫的一些参数,如请求头、下载延迟等。 5. 运行爬虫:使用命令行工具或Scrapy API启动爬虫。 总之,Scrapy是一个功能强大、易于使用的Python爬虫框架,可以帮助开发者快速地构建高效、可扩展的爬虫应用。 ### 回答2: Scrapy是一个基于Python的开源网络爬虫框架。它可以在一个爬虫工程师的控制下自动执行爬取任务,不仅可方便地快速抓取各类网站数据,而且还能够轻松地对爬取到的数据进行处理、存储和展示。 Scrapy的功能包括了爬虫组件、下载器、中间件框架、优化器和调度器。其中,爬虫组件是Scrapy的核心模块,它负责实现对爬取网站的访问和数据解析,并抽象成Scrapy的Item类型。下载器用于获取相应网页的HTTP数据,中间件框架可以进行层层拦截和处理各种网络请求,以支持一些高级事务。另外,优化器和调度器则主要负责控制整个爬虫工程师的流程和顺序。 Scrapy的使用方式极为简单。在使用Scrapy之前,首先需要使用命令“scrapy startproject”来创建一个工程,然后可在该工程下进一步创建一到多个爬虫组件并指定需要爬取的网址。接下来,我们可定义一个Item类型,来解决需要爬取的数据对象的问题。在爬虫组件中,我们需要定义如何爬取和解析数据。同时,如果希望实现登录功能,我们可在中间件框架中进行相应设置。而对于数据存储和展示等操作,我们也可以在Item Pipeline中定义。 总结起来,Scrapy框架解决了网页数据爬取的问题,提供了简单易用的API以及丰富的库,可以完成高效而优质的爬取,而且功能上也足以满足个人爬虫开发的需求。如果我们希望进一步学习更多Scrapy的应用,我们可以参考Scrapy官方文档、StackOverflow和GitHub的相关资源,以及优秀的一些自媒体博文和经验分享。 ### 回答3: Scrapy是一个Python编写的用于Web数据采集的高级抓取框架。它是一个基于Twisted框架的异步网络库,可以更高效地处理网页的并发请求和响应。Scrapy框架的架构模式和流程非常清晰,包括了一系列数据处理工具和插件,方便用户进行数据的爬取、处理、存储和展示。 Scrapy框架主要包括以下几个模块: 1. Engine: 引擎控制所有模块进行协作,调度模块接收引擎发来的请求,并将其转发给下载器,同时将下载器获得的响应反馈给引擎。 2. Scheduler: 调度器负责接收并存储引擎发来的请求,并按照一定的策略进行调度,将请求发送给下载器。 3. Downloader: 下载器负责请求网络数据,将响应返回给引擎。 4. Spider: 爬虫负责解析、处理响应,并产生需要的请求数据,将其发给引擎。爬虫是用户自定义的模块,用于指定如何对网站进行数据抓取和处理。 5. Item Pipeline: 项目管道用于处理从Spider中获取到的Item,可以对Item进行过滤、验证、清洗和存储等操作。 6. Middlewares: 中间件用于修改在引擎和下载器之间传递的请求和响应,可以被用于添加请求头、代理、IP池、处理Cookie等操作。 使用Scrapy,可以很好地解决数据采集过程中遇到的各种问题,如并发请求、防反爬虫、分布式爬取、自动重试、日志管理等。同时,Scrapy还提供了强大的数据处理工具,如XPath和CSS选择器,能够使得用户更加轻松地解析网页并提取所需要的信息。因此,Scrapy在反爬虫、数据采集等领域具有广泛的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独角兽小马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值