返回顶部
首页 > 资讯 > 精选 >Scrapy的中间件如何使用
  • 159
分享到

Scrapy的中间件如何使用

2023-07-02 09:07:40 159人浏览 薄情痞子
摘要

这篇文章主要讲解了“scrapy的中间件如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Scrapy的中间件如何使用”吧!Scrapy 结构概述:一、下载器中间件(Downloader

这篇文章主要讲解了“scrapy中间件如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Scrapy的中间件如何使用”吧!

    Scrapy 结构概述:

    Scrapy的中间件如何使用

    一、下载器中间件(Downloader Middleware)

    如上图标号4、5处所示,下载器中间件用于处理scrapy的request和response的钩子框架,如在request中设置代理ip,header等,检测response的Http响应码等。

    scrapy已经自带来一堆下载器中间件。

    {    'scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware': 100,    'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware': 300,    'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware': 350,    'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware': 400,    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': 500,    'scrapy.downloadermiddlewares.retry.RetryMiddleware': 550,    'scrapy.downloadermiddlewares.ajaxcrawl.AjaxCrawlMiddleware': 560,    'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware': 580,    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 590,    'scrapy.downloadermiddlewares.redirect.RedirectMiddleware': 600,    'scrapy.downloadermiddlewares.cookies.CookiesMiddleware': 700,    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 750,    'scrapy.downloadermiddlewares.stats.DownloaderStats': 850,    'scrapy.downloadermiddlewares.httpcache.HttpCacheMiddleware': 900,}

    上面就是默认启用的下载器中间件,其各个中间件的作用参考一下官方文档:Scrapy download-middleware

    自定义下载器中间件

    有时我们需要编写自己的一些下载器中间件,如使用代理池,随机更换user-agent等,要使用自定义的下载器中间件,就需要在setting文件中激活我们自己的实现类,如下:

    DOWNLOADERMIDDLEWARES = {    'myproject.middlewares.Custom_A_DownloaderMiddleware': 543,    'myproject.middlewares.Custom_B_DownloaderMiddleware': 643,    'myproject.middlewares.Custom_B_DownloaderMiddleware': None,}

    设置值是个DICT,key是我们自定义的类路径,后面数字是执行顺序,数字越小,越靠近引擎,数字越大越靠近下载器,所以数字越小的,processrequest()优先处理;数字越大的,process_response()优先处理;若需要关闭某个中间件直接设为None即可。
    (PS. 如果两个下载器的没有强制的前后关系,数字大小没什么影响)

    实现下载器我们需要重写以下几个方法:

    • 对于请求的中间件实现 process_request(request, spider);

    • 对于处理回复中间件实现process_response(request, response, spider);

    • 以及异常处理实现 process_exception(request, exception, spider)

    process_request(request, spider)

    process_request:可以选择返回None、Response、Request、raise IgnoreRequest其中之一。

    • 如果返回None,scrapy将继续处理该request,执行其他的中间件的响应方法。直到合适的下载器处理函数(downloader handler)被调用,该request被执行,其response被下载。

    • 如果其返回Response对象,Scrapy将不会调用任何其他的process_request()或process_exception()方法,或相应地下载函数; 其将返回该response。已安装的中间件的process_response()方法则会在每个response返回时被调用

    • 如果其返回Request对象,Scrapy则停止调用process_request方法并重新调度返回的request。当新返回的request被执行后,相应地中间件链将会根据下载的response被调用。

    • 如果其raise IgnoreRequest,则安装的下载中间件的process_exception()方法会被调用。如果没有任何一个方法处理该异常, 则request的errback(Request.errback)方法会被调用。如果没有代码处理抛出的异常, 则该异常被忽略且不记录(不同于其他异常那样)。

    通常返回None较常见,它会继续执行爬虫下去

    process_response(request, response, spider)

    当下载器完成HTTP请求,传递响应给引擎的时候调用,它会返回 ResponseRequestIgnoreRequest三种对象的一种

    • 若返回Response对象,它会被下个中间件中的process_response()处理

    • 若返回Request对象,中间链停止,然后返回的Request会被重新调度下载

    • 抛出IgnoreRequest,回调函数 Request.errback将会被调用处理,若没处理,将会忽略

    process_exception(request, exception, spider)

    当下载处理器(download handler)或process_request()抛出异常(包括 IgnoreRequest 异常)时, Scrapy调用 process_exception() ,通常返回None,它会一直处理异常

    from_crawler(cls, crawler)

    这个类方法通常是访问settings和signals的入口函数

    例如下面2个例子是更换user-agent和代理ip的下载中间件

    # setting中设置USER_AGENT_LIST = [ \    "Mozilla/5.0 (windows NT 6.1; WOW64) AppleWEBKit/537.1 (Khtml, like Gecko) Chrome/22.0.1207.1 Safari/537.1", \    "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11", \    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6", \    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6", \    "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1", \    "Mozilla/5.0 (X11; linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5", \    "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5", \    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \    "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", \    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", \    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", \    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", \    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", \    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3", \    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24", \    "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24", \    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.132 Safari/537.36", \    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0"]PROXIES = [    '1.85.220.195:8118',    '60.255.186.169:8888',    '118.187.58.34:53281',    '116.224.191.141:8118',    '120.27.5.62:9090',    '119.132.250.156:53281',    '139.129.166.68:3128']

    代理ip中间件

    import randomclass Proxy_Middleware():    def __init__(self, crawler):        self.proxy_list = crawler.settings.PROXY_LIST        self.ua_list = crawler.settings.USER_AGENT_LIST@claSSMethoddef from_crawler(cls, crawler):    return cls(crawler)    def process_request(self, request, spider):        try:ua = random.choice(self.ua_list)        request.headers.setdefault('User-Agent', ua)                    proxy_ip_port = random.choice(self.proxy_list)            request.meta['proxy'] = 'http://' + proxy_ip_port        except request.exceptions.RequestException:            spider.logger.error('some error happended!')

    重试中间件

    有时使用代理会被远程拒绝或超时等错误,这时我们需要换代理ip重试,重写scrapy.downloadermiddlewares.retry.RetryMiddleware

    from scrapy.downloadermiddlewares.retry import RetryMiddlewarefrom scrapy.utils.response import response_status_messageclass My_RetryMiddleware(RetryMiddleware):def __init__(self, crawler):        self.proxy_list = crawler.settings.PROXY_LIST        self.ua_list = crawler.settings.USER_AGENT_LIST@classmethoddef from_crawler(cls, crawler):    return cls(crawler)    def process_response(self, request, response, spider):        if request.meta.get('dont_retry', False):            return response        if response.status in self.retry_http_codes:            reason = response_status_message(response.status)            try:                ua = random.choice(self.ua_list)        request.headers.setdefault('User-Agent', ua)                    proxy_ip_port = random.choice(self.proxy_list)            request.meta['proxy'] = 'http://' + proxy_ip_port            except request.exceptions.RequestException:                spider.logger.error('获取讯代理ip失败!')            return self._retry(request, reason, spider) or response        return response
    # scrapy中对接seleniumfrom scrapy.http import HtmlResponsefrom selenium import webdriverfrom selenium.common.exceptions import TimeoutExceptionfrom gp.configs import *class ChromeDownloaderMiddleware(object):    def __init__(self):        options = webdriver.ChromeOptions()        options.add_argument('--headless')  # 设置无界面        if CHROME_PATH:            options.binary_location = CHROME_PATH        if CHROME_DRIVER_PATH:  # 初始化Chrome驱动            self.driver = webdriver.Chrome(chrome_options=options, executable_path=CHROME_DRIVER_PATH)          else:            self.driver = webdriver.Chrome(chrome_options=options)  # 初始化Chrome驱动    def __del__(self):        self.driver.close()    def process_request(self, request, spider):        try:            print('Chrome driver begin...')            self.driver.get(request.url)  # 获取网页链接内容            return HtmlResponse(url=request.url, body=self.driver.page_source, request=request, encoding='utf-8',                                status=200)  # 返回HTML数据        except TimeoutException:            return HtmlResponse(url=request.url, request=request, encoding='utf-8', status=500)        finally:            print('Chrome driver end...')

    二、Spider中间件(Spider Middleware)

    如文章第一张图所示,spider中间件用于处理response及spider生成的item和Request

    启动自定义spider中间件必须先开启settings中的设置

    SPIDER_MIDDLEWARES = {    'myproject.middlewares.CustomSpiderMiddleware': 543,    'scrapy.spidermiddlewares.offsite.OffsiteMiddleware': None,}

    同理,数字越小越靠近引擎,process_spider_input()优先处理,数字越大越靠近spider,process_spider_output()优先处理,关闭用None

    编写自定义spider中间件

    process_spider_input(response, spider)

    当response通过spider中间件时,这个方法被调用,返回None

    process_spider_output(response, result, spider)

    当spider处理response后返回result时,这个方法被调用,必须返回Request或Item对象的可迭代对象,一般返回result

    process_spider_exception(response, exception, spider)

    当spider中间件抛出异常时,这个方法被调用,返回None或可迭代对象的Request、dict、Item

    补充一张图:

    Scrapy的中间件如何使用

    感谢各位的阅读,以上就是“Scrapy的中间件如何使用”的内容了,经过本文的学习后,相信大家对Scrapy的中间件如何使用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

    --结束END--

    本文标题: Scrapy的中间件如何使用

    本文链接: https://lsjlt.com/news/340731.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • Scrapy的中间件如何使用
      这篇文章主要讲解了“Scrapy的中间件如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Scrapy的中间件如何使用”吧!Scrapy 结构概述:一、下载器中间件(Downloader...
      99+
      2023-07-02
    • Scrapy 之中间件(Middleware)的具体使用
      目录一、下载器中间件(Downloader Middleware)process_request(request, spider)process_response(request, ...
      99+
      2024-04-02
    • 如何使用scrapy-splash
      这篇文章主要介绍了如何使用scrapy-splash,编程网小编觉得不错,现在分享给大家,也给大家做个参考,一起跟随编程网小编来看看吧!1.scrapy_splash是scrapy的一个组件scrapy_splash加载js数据基于Spla...
      99+
      2023-06-06
    • 如何在python中使用scrapy模块
      这篇文章将为大家详细讲解有关如何在python中使用scrapy模块,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。二、基本使用2.1 环境安装1.linux和mac操作系统:pip ...
      99+
      2023-06-06
    • scrapy 爬虫学习二[中间件的学习]
      scrapy源码解析参考连接:https://www.jianshu.com/p/d492adf17312 ,直接看大佬的就行了,这里便就不多说了。 今天要学习的是:Scrapy框架中的download middlerware【下载中间件...
      99+
      2023-01-31
      爬虫 中间件 scrapy
    • mysql中mycat 中间件如何使用
      本篇文章给大家分享的是有关mysql中mycat 中间件如何使用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一,什么是mycat一个彻底开源...
      99+
      2024-04-02
    • MySQL中如何使用DAL中间件
      本篇文章给大家分享的是有关MySQL中如何使用DAL中间件,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Atlas是由 Qihoo  ...
      99+
      2024-04-02
    • Node中如何使用Express中间件
      本文小编为大家详细介绍“Node中如何使用Express中间件”,内容详细,步骤清晰,细节处理妥当,希望这篇“Node中如何使用Express中间件”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起...
      99+
      2024-04-02
    • nodejs中Express中间件如何使用
      本篇文章给大家分享的是有关nodejs中Express中间件如何使用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Express是一个基于No...
      99+
      2024-04-02
    • Mysql如何使用Maxscale中间件
      这篇文章给大家介绍Mysql如何使用Maxscale中间件,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。 背景:[root@node4 ~]# mysql...
      99+
      2024-04-02
    • ASP.NET Core中间件如何使用
      今天小编给大家分享一下ASP.NET Core中间件如何使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1.前言...
      99+
      2023-06-29
    • python中Scrapy shell的使用
      前言: 我们想要在爬虫中使用xpath、beautifulsoup、正则表达式,css选择器等来提取想要的数据,但是因为scrapy是一个比较重的框架,每次运行都要等到一段时间,因此...
      99+
      2024-04-02
    • python中如何使用Scrapy实现定时爬虫
      这篇文章将为大家详细讲解有关python中如何使用Scrapy实现定时爬虫,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。python的数据类型有哪些python的数据类型:1. 数字类型,包括int(整型...
      99+
      2023-06-14
    • VUE Nuxt.js中间件最佳实践:如何正确使用中间件
      1. 什么是中间件? 中间件是Vue Nuxt.js中的一种钩子函数,它可以在请求到达路由处理程序之前执行某些操作。中间件可以用于各种目的,例如: 身份验证:检查用户是否已登录,并拒绝未登录用户的访问。 授权:检查用户是否有权访问请求...
      99+
      2024-02-04
      Vue Nuxt.js 中间件 最佳实践
    • 如何使用分库分表中间件
      这篇文章主要介绍“如何使用分库分表中间件”,在日常操作中,相信很多人在如何使用分库分表中间件问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何使用分库分表中间件”的疑惑有所帮...
      99+
      2024-04-02
    • selenium在scrapy中的使用代码
      在通过scrapy框架进行某些网站数据爬取的时候,往往会碰到页面动态数据加载的情况发生,如果直接使用scrapy对其url发请求,是绝对获取不到那部分动态加载出来的数据值。但是通过观...
      99+
      2024-04-02
    • Django中间件的使用
      中间件(middleware) 中间件应用于request与服务端之间和服务端与response之间,客户端发起请求到服务端接收可以通过中间件,服务端返回响应与客户端接收响应可以通过中间件,也就是说中间件可以处理request和resp...
      99+
      2023-01-30
      中间件 Django
    • 如何使用ActiveMQ中间件方式发送邮件
      前言 在大型互联网公司中,一般都会搭建内部的消息服务平台,处理公司内部的各种消息服务,比如:发送邮件、发送短信、微信推送等,公司内部消息平台再去调用第三发消息平台。消息服务平台的接...
      99+
      2024-04-02
    • scrapy的简单使用
      使用之前的创建虚拟环境方法(pipenv) 创建虚拟环境并进入虚拟环境 mkdir douban cd douban pipenv install pipenv shell 再安装我们的scrapy pipenv install s...
      99+
      2023-01-30
      简单 scrapy
    • 如何使用和配置Mysql KingShard中间件
      如何使用和配置Mysql KingShard中间件,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。 ...
      99+
      2024-04-02
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作