zoukankan      html  css  js  c++  java
  • Scrapy爬虫框架第五讲(linux环境)【download middleware用法】

    DOWNLOAD MIDDLEWRE用法详解

                                 

    通过上面的Scrapy工作架构我们对其功能进行下总结:

    (1)、在Scheduler调度出队列时的Request送给downloader下载前对其进行修改

    (2)、在下载生成后的Response发送给Spider并在Spider对其解析之前对其修改

    【这里我们将scheduler spiders downloader middlewares downloader看作四个小伙伴做游戏进一步进行理解 】

    (1)scheduler对spider说:请把request给我,spiders收到信息后,就说这是我的request,拿去吧

    (2)scheduler收到request后要去找名叫downloader的小伙伴才能去服务器上下载数据,

    (3)这时,名叫downloader middlewares的小伙伴跳出来说,得怎么没我什么事了,于是它站在了scheduler和downloader中间,愤恨地说出了自己的价值(我可以对scheduler你的request进行如增加http header信息,增加proxy信息,重定向,失败重试等操作!)


    Scrapy框架提供了多种内置的downloader middleware(摘自http://scrapy-chs.readthedocs.io/zh_CN/1.0/topics/downloader-middleware.html#topics-downloader-middleware-ref,小伙伴们了解即可)

    'scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware':100,【该中间件过滤所有robots.txt eclusion standard中禁止的request。】
    'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware':200,【该中间件完成某些使用 Basic access authentication (或者叫HTTP认证)的spider生成的请求的认证过程。】
    'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware':300,【该中间件设置 DOWNLOAD_TIMEOUT 指定的request下载超时时间.】
    'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware':400,【该中间件设置 DEFAULT_REQUEST_HEADERS 指定的默认request header】
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware':500,【用于覆盖spider的默认user agent的中间件,要使得spider能覆盖默认的user agent,其 user_agent 属性必须被设置。】

    'scrapy.downloadermiddlewares.retry.RetryMiddleware':600,【该中间件将重试可能由于临时的问题,例如连接超时或者HTTP 500错误导致失败的页面。】
    'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware':650,【该中间件根据meta-refresh html标签处理request重定向。】
    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware':700,【该中间件提供了对压缩(gzip, deflate)数据的支持】
    'scrapy.downloadermiddlewares.redirect.RedirectMiddleware':750,【该中间件根据response的状态处理重定向的request。】
    'scrapy.downloadermiddlewares.cookies.CookiesMiddleware':800,【该中间件使得爬取需要cookie(例如使用session)的网站成为了可能。 其追踪了web server发送的cookie,并在之后的request中发送回去, 就如浏览器所做的那样】
    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware':850,【该中间件提供了对request设置HTTP代理的支持。您可以通过在 Request 对象中设置 proxy 元数据来开启代理。】


    这里给小伙伴们普及一个概念:我们发现在每个内置中间件后面都跟了数字:这些数字是什么意思呢?

    答:我们以食堂吃饭为例,就以我们学校二食堂,你去打饭正值中午11.50,这时你会发现人多到你想骂娘,所有你需要排队等候,我们以此类比,你打的饭菜就相当于request请求,当你需要将request请求送给download组件(你成功打到饭菜)前你需要排队,在这数字越小说明你在队伍中的位置越靠前,即你的优先级越高,而数字越大的人排的越靠后就可能吃不到饭了,小伙伴们明白了没?   


    Scrapy框架不仅定义了自己的中间件,我们还可以根据需要进行自我定义:

    class scrapy.downloadermiddlewares.DownloaderMiddleware

    这里我们定义自己的downloader middleware ,而每个类都定义了一个或多个方法,我们介绍以下三个核心的方法:

    (1)、process_request(request,spider) 【参数一:request (Request 对象) –即待处理的request对象 /参数二:spider (Spider 对象) – 该request对应的spider】

    方法分析:

    该方法在request被引擎调度给downloader之前被调用

    该方法有4种返回结果:我们依次来分析:
    (1)、返回None:

    此时scrapy会继续处理该Request,即不同的Downloader middleware 按优先级的顺序修改该Request,并送给Downloader执行

    (2)、返回Response:

    此时scrapy不会再执行其他的process_request和process_exception方法,并调用Downloader middleware的每个process_response方法,将Request送给spider组件

    (3)、返回Request对象

    此时scrapy会返回process_request方法并重新执行(即重试),直到新的Request被执行,才返回Response

    (4)、返回IgnoreRequest异常

    此时会依次执行Downloader middleware的process_exception方法,如果process_exception方法无法解决,那么就会回调Request的errback方法,如果还无法解决,那么该异常就会被忽略


    下面我们来打个比方帮助小伙伴们理解下上面四种放回情况:

    我们以去食堂吃饭为例:(1)、就是你拿着饭卡成功打到了饭菜(2)、你拿着饭卡去打饭,食堂阿姨给了你一袋子东西(但遗憾的是这不是饭菜,即你打了假饭菜(3)、你拿着饭卡去打饭,食堂阿姨说你可能拿了假饭卡,重新去排队打饭吧(4)、你拿着饭卡去打饭,食堂阿姨直接把你忽略了


    小伙伴们明白了吗?如果有问题,不要着急,我们接着往下看:
    该方法使用实例分析:

    下面小伙伴们让我们使用process_request方法实现代理的设置(下面实验是基于win10 pycharm中运行的 )

    首先:启动终端新建项目:scrapy startproject httpbintest

    cd httpbinbest  ----scrapy genspider httpbin httpbin.org

    接着:利用pycharm启动项目

    改写httpbin.py

    利用alt+f12启动pycharm的terminal:执行命令:scrapy crawl httpbin

    得到如下输出:(这里我只贴出了部分)

    这里我们可以看到成功爬取啦,小伙伴们我们注意到origin字段(这就是你本机电脑的ip,你可以把它复制进百度,一查,定位看看,这里我的是镇江联通)

    下面我们要实现更换该ip来实现对网站的爬取(即伪装自我)

    打开:middleware.py并修改

    这里小伙伴们可以上讯代理购买几个i(本人发现系统代理需要输密码,所以出了9块大洋买了几个代理ip)【注释:小伙伴们别忘了导入logging模块】

    这里我们返回值为None,具体什么意思参见上文

    最后打开:settings.py(项目配置文件)启动中间件

    得到如下输出:(这里我也只贴了部分)

    小伙伴们我们可以将成功运行的ip百度一下,你会发现地址已换,我们成功实现了伪装我们的ip进行爬取,是不是很有意思!


    (2)、process_response(request,response,spider) 【参数一:Request对象 参数二:Response对象,即被处理的Response 参数三:Spider对象,即Response对应的Spider】

    该方法返回四种结果,我们依次来分析:

    (1)、返回Request对象

    此时,优先级更低的Downloader Middleware 的process_response方法将不会被调用,该Request会重回队列被process_request处理,即返回了上一个Request的(1)

    (2)、返回Response对象

    此时,将会执行更低优先级的process_response方法,继续处理Response

    (3)、返回IgnoreRequest异常

    此时同Request的(4)

    该方法使用实例分析

    改写middleware.py(这里我只贴出了部分)

    改下httpbin.py

    得到的输出结果如下:

    我们来分析下过程:downloader获取Response之后经过middleware改写,将原本的状态吗变成了206再传给Response,所以我们得到的Response的状态吗成立206了

    总结:process_response主要用来改写你downloader返回的Response


    (3)、process_exception(request,exception,spider)【参数一:产生异常的Request对象 参数二:即抛出的异常exception对象 参数三:Request对应的spider】----主要用来处理由process_request产生的异常

    该方法返回三种结果,我们依次来分析下:

    (1)、返回None

    此时,更低优先级的Downloader  Middleware的process_exception方法将会被调用,直到所有的方法都被调度完毕【错误没有被纠正】

    (2)、返回Response

    此时,更低优先级的Downloader Middleware的process_exception方法将不会被调用,而依次去执行所有中间件的process_response方法【错误被纠正了】

    (3)、返回Request

    此时,更低优先级的Downloader Middleware的process_exception方法将不会被调用,而依次去执行process_request方法【回炉重造了】


    总结:

    (1)Downloader Middlewares 由scrapy内置的middleware和你自己定义的middlewares组成

    (2)如小伙伴不想使用scrapy内置的middlewares可以'scrapy.downloadermiddlewares.retry.RetryMiddleware':None,这样就不启用了

    (3)各个middlewares后面的数字表示优先级,数字越小表明你的优先级越高(越远离downloader即先进去后出来),数字越大表明优先级越低(越靠近downloader即后进去先出来)

    (4)我们主要使用downloader middlewares 来改变User-Agent、设置代理、cookies等反反爬虫机制(具体后面我们以实例详谈)

    小伙伴们理解了吗?

     

                                                                                                                                                                                                                                                               

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                

  • 相关阅读:
    jQuery图片翻转弹出动画特效
    HTML5来了,7个混合式移动开发框架
    10款很好用的 jQuery 图片滚动插件
    JS图片自动和可控的轮播切换特效
    CSS3扇形动画菜单 鼠标滑过扇形展开动画
    css里面的几个你不知道的属性
    JS判断是否是微信打开页面
    js的escape()、encodeURI()、encodeURIComponent()区别详解
    使用HTML5的十大原因
    Hybrid App开发 四大主流移平台分析
  • 原文地址:https://www.cnblogs.com/518894-lu/p/9037616.html
Copyright © 2011-2022 走看看