中间件的简介

  1.中间件的作用

在scrapy运行的整个过程中,对scrapy框架运行的某些步骤做一些适配自己项目的动作.

   例如scrapy内置的HttpErrorMiddleware,可以在http请求出错时做一些处理.

2.中间件的使用方法

配置settings.py.详见scrapy文档 https://doc.scrapy.org

中间件的分类

  scrapy的中间件理论上有三种(Schduler Middleware,Spider Middleware,Downloader Middleware),在应用上一般有以下两种

1.爬虫中间件Spider Middleware

主要功能是在爬虫运行过程中进行一些处理.

  2.下载器中间件Downloader Middleware

主要功能在请求到网页后,页面被下载时进行一些处理.

中间件的方法

1.Spider Middleware有以下几个函数被管理:

- process_spider_input 接收一个response对象并处理,

位置是Downloader-->process_spider_input-->Spiders(Downloader和Spiders是scrapy官方结构图中的组件)

- process_spider_exception spider出现的异常时被调用

- process_spider_output 当Spider处理response返回result时,该方法被调用

- process_start_requests 当spider发出请求时,被调用

    位置是Spiders-->process_start_requests-->Scrapy Engine(Scrapy Engine是scrapy官方结构图中的组件)

  2.Downloader Middleware有以下几个函数被管理

   - process_request  request通过下载中间件时,该方法被调用

   - process_response 下载结果经过中间件时被此方法处理

   - process_exception 下载过程中出现异常时被调用

编写中间件时,需要思考要实现的功能最适合在那个过程处理,就编写哪个方法.

中间件可以用来处理请求,处理结果或者结合信号协调一些方法的使用等.也可以在原有的爬虫上添加适应项目的其他功能,这一点在扩展中编写也可以达到目的,实际上扩展更加去耦合化,推荐使用扩展.

代码示例

下载中间件代码示例

from scrapy.http import HtmlResponse
from scrapy.http import Request class Md1(object):
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
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
print('md1.process_request',request)
# 1. 返回Response
# import requests
# result = requests.get(request.url)
# return HtmlResponse(url=request.url, status=200, headers=None, body=result.content)
# 2. 返回Request
# return Request('https://dig.chouti.com/r/tec/hot/1') # 3. 抛出异常
# from scrapy.exceptions import IgnoreRequest
# raise IgnoreRequest # 4. 对请求进行加工(*)
# request.headers['user-agent'] = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" 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
print('m1.process_response',request,response)
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

配置

DOWNLOADER_MIDDLEWARES = {
#'xdb.middlewares.XdbDownloaderMiddleware': 543,
# 'xdb.proxy.XdbProxyMiddleware':751,
'xdb.md.Md1':666,
'xdb.md.Md2':667,
}

爬虫中间件下载示例

编写类

class Sd1(object):
# 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()
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, dict 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 Response, dict
# 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

配置

SPIDER_MIDDLEWARES = {
# 'xdb.middlewares.XdbSpiderMiddleware': 543,
'xdb.sd.Sd1': 666,
'xdb.sd.Sd2': 667,
}

scrapy之中间件的更多相关文章

  1. 彻底搞懂Scrapy的中间件(一)

    中间件是Scrapy里面的一个核心概念.使用中间件可以在爬虫的请求发起之前或者请求返回之后对数据进行定制化修改,从而开发出适应不同情况的爬虫. "中间件"这个中文名字和前面章节讲到 ...

  2. scrapy的中间件Downloader Middleware实现User-Agent随机切换

    scrapy的中间件Download Middleware实现User-Agent随机切换   总架构理解Middleware 通过scrapy官网最新的架构图来理解: 从图中我们可以看出,在spid ...

  3. scrapy框架中间件配置代理

    scrapy框架中间件配置代理import random#代理池PROXY_http = [ '106.240.254.138:80', '211.24.102.168:80',]PROXY_http ...

  4. Scrapy的中间件(一)

    中间件是Scrapy里面的一个核心概念.使用中间件可以在爬虫的请求发起之前或者请求返回之后对数据进行定制化修改,从而开发出适应不同情况的爬虫. "中间件"这个中文名字和前面章节讲到 ...

  5. Scrapy下载中间件的优先级(神踏马值越小优先级越高)

    自从之前看的一篇讲Scrapy下载中间件的文章后,一直认为设置里下载中间件的优先级数值越小,越优先,最近要抓的网站反爬增强了,所以需要使用代理ip,但是由于使用的是免费代理以至于经常失效,需要对失效的 ...

  6. Python爬虫从入门到放弃(二十三)之 Scrapy的中间件Downloader Middleware实现User-Agent随机切换

    总架构理解Middleware 通过scrapy官网最新的架构图来理解: 这个图较之前的图顺序更加清晰,从图中我们可以看出,在spiders和ENGINE提及ENGINE和DOWNLOADER之间都可 ...

  7. Scrapy 框架 中间件,信号,定制命令

    中间件 下载器中间件 写中间件 from scrapy.http import HtmlResponse from scrapy.http import Request class Md1(objec ...

  8. 彻底搞懂Scrapy的中间件(三)

    在前面两篇文章介绍了下载器中间件的使用,这篇文章将会介绍爬虫中间件(Spider Middleware)的使用. 爬虫中间件 爬虫中间件的用法与下载器中间件非常相似,只是它们的作用对象不同.下载器中间 ...

  9. 彻底搞懂Scrapy的中间件(二)

    在上一篇文章中介绍了下载器中间件的一些简单应用,现在再来通过案例说说如何使用下载器中间件集成Selenium.重试和处理请求异常. 在中间件中集成Selenium 对于一些很麻烦的异步加载页面,手动寻 ...

随机推荐

  1. 一条经典SQL语句优化实例

    1.概述 如下SQL语句发生严重消耗资源的问题,使得OS's load average会在30以上,一条语句需要执行上百秒. /*PIXPatient 184176条DomainPatient 184 ...

  2. eclipse启动无响应,老是加载不了revert resources,或停留在Loading workbench状态

    做开发的同学们或多或少的都会遇到eclipse启动到一定程度时,就进入灰色无响应状态再也不动了.启动画面始终停留在Loading workbench状态.反复重启,状态依旧. 多数情况下,应该是非正常 ...

  3. asp.net 判断session是否过期

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  4. [android] AndroidManifest.xml -【manifest】

    <manifest> 原文链接:http://www.android-doc.com/guide/topics/manifest/manifest-element.html 最早引入的AP ...

  5. web 前端 转盘界面

    http://www.cnblogs.com/arfeizhang/p/turntable.html "如果有个做转盘的需求,你准备怎么做?设计师只会提供一个转盘的图片,其余都需要你完成,不 ...

  6. JavaScript 二、eval 和 with 函数

    /* * ========================================================= * * JavaScript 词法欺骗 * * 1.欺骗词法作用域,会导致 ...

  7. Hadoop日志分析系统启动脚本

    Hadoop日志分析系统启动脚本 #!/bin/bash #Flume日志数据的根文件夹 root_path=/flume #Mapreduce处理后的数据文件夹 process_path=/proc ...

  8. Maven编译失败,提示No compiler is provided in this enviroment. Perhaps you are running on a JRE rathen a JDK ?

    用maven对项目进行构建时,提示No compiler is provided in this enviroment. Perhaps you are running on a JRE rathen ...

  9. 【BZOJ3585/3339】mex 莫队算法+分块

    [BZOJ3585]mex Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. ...

  10. 记一个在docker中运行多线程event_loop.run_forever()的bug

    问题简介 我写爬虫,用到了asyncio相关的事件循环,新建了一个线程去run_forever(),在docker中运行.后来程序有异常,主线程挂了,但是竟然不报错.查了很久,才找出来. 如果你新建一 ...