Scrapy 扩展中间件: 针对特定响应状态码,使用代理重新请求
0.参考
1.主要实现
实际爬虫过程中如果请求过于频繁,通常会被临时重定向到登录页面即302,甚至是提示禁止访问即403,因此可以对这些响应执行一次代理请求:
(1) 参考原生 redirect.py 模块,满足 dont_redirect 或 handle_httpstatus_list 等条件时,直接传递 response
(2) 不满足条件(1),如果响应状态码为 302 或 403,使用代理重新发起请求
(3) 使用代理后,如果响应状态码仍为 302 或 403,直接丢弃
2.代码实现
保存至 /site-packages/my_middlewares.py
from w3lib.url import safe_url_string
from six.moves.urllib.parse import urljoin from scrapy.exceptions import IgnoreRequest class MyAutoProxyDownloaderMiddleware(object): def __init__(self, settings):
self.proxy_status = settings.get('PROXY_STATUS', [302, 403])
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html?highlight=proxy#module-scrapy.downloadermiddlewares.httpproxy
self.proxy_config = settings.get('PROXY_CONFIG', 'http://username:password@some_proxy_server:port') @classmethod
def from_crawler(cls, crawler):
return cls(
settings = crawler.settings
) # See /site-packages/scrapy/downloadermiddlewares/redirect.py
def process_response(self, request, response, spider):
if (request.meta.get('dont_redirect', False) or
response.status in getattr(spider, 'handle_httpstatus_list', []) or
response.status in request.meta.get('handle_httpstatus_list', []) or
request.meta.get('handle_httpstatus_all', False)):
return response if response.status in self.proxy_status:
if 'Location' in response.headers:
location = safe_url_string(response.headers['location'])
redirected_url = urljoin(request.url, location)
else:
redirected_url = '' # AutoProxy for first time
if not request.meta.get('auto_proxy'):
request.meta.update({'auto_proxy': True, 'proxy': self.proxy_config})
new_request = request.replace(meta=request.meta, dont_filter=True)
new_request.priority = request.priority + 2 spider.log('Will AutoProxy for <{} {}> {}'.format(
response.status, request.url, redirected_url))
return new_request # IgnoreRequest for second time
else:
spider.logger.warn('Ignoring response <{} {}>: HTTP status code still in {} after AutoProxy'.format(
response.status, request.url, self.proxy_status))
raise IgnoreRequest return response
3.调用方法
(1) 项目 settings.py 添加代码,注意必须在默认的 RedirectMiddleware 和 HttpProxyMiddleware 之间。
# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
# 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware': 600,
'my_middlewares.MyAutoProxyDownloaderMiddleware': 601,
# 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 750,
}
PROXY_STATUS = [302, 403]
PROXY_CONFIG = 'http://username:password@some_proxy_server:port'
4.运行结果
2018-07-18 18:42:35 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://httpbin.org/> (referer: None)
2018-07-18 18:42:38 [test] DEBUG: Will AutoProxy for < http://httpbin.org/status/302> http://httpbin.org/redirect/1
2018-07-18 18:42:43 [test] DEBUG: Will AutoProxy for < https://httpbin.org/status/403>
2018-07-18 18:42:51 [test] WARNING: Ignoring response <302 http://httpbin.org/status/302>: HTTP status code still in [302, 403] after AutoProxy
2018-07-18 18:42:52 [test] WARNING: Ignoring response <403 https://httpbin.org/status/403>: HTTP status code still in [302, 403] after AutoProxy
代理服务器 log:
squid [18/Jul/2018:18:42:53 +0800] "GET http://httpbin.org/status/302 HTTP/1.1" 302 310 "-" "Mozilla/5.0" TCP_MISS:HIER_DIRECT
squid [18/Jul/2018:18:42:54 +0800] "CONNECT httpbin.org:443 HTTP/1.1" 200 3560 "-" "-" TCP_TUNNEL:HIER_DIRECT
Scrapy 扩展中间件: 针对特定响应状态码,使用代理重新请求的更多相关文章
- 9. http协议_响应状态码_页面渲染流程_路由_中间件
1. http协议 超文本传输协议 协议详细规定了 浏览器 和 万维网服务器 之间互相通信的规则 客户端与服务端通信时传输的内容我们称之为报文(请求报文.响应报文) 常见的发送 get 请求方式 在浏 ...
- TCP/IP协议族(一) HTTP简介、请求方法与响应状态码
接下来想系统的回顾一下TCP/IP协议族的相关东西,当然这些东西大部分是在大学的时候学过的,但是那句话,基础的东西还是要不时的回顾回顾的.接下来的几篇博客都是关于TCP/IP协议族的,本篇博客就先简单 ...
- ASP.NET Core错误处理中间件[4]: 响应状态码页面
StatusCodePagesMiddleware中间件与ExceptionHandlerMiddleware中间件类似,它们都是在后续请求处理过程中"出错"的情况下利用一个错误处 ...
- http响应状态码大全
http响应状态码大全 http状态返回代码 1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态代码. http状态返回代码 代码 说明100 (继续) 请求者应当继续提出请求. 服 ...
- iOS开发——网络篇——HTTP/NSURLConnection(请求、响应)、http响应状态码大全
一.网络基础 1.基本概念> 为什么要学习网络编程在移动互联网时代,移动应用的特征有几乎所有应用都需要用到网络,比如QQ.微博.网易新闻.优酷.百度地图只有通过网络跟外界进行数据交互.数据更新, ...
- HTTP响应状态码参考
HTTP响应状态码参考: 1xx:信息 Continue 服务器仅接收到部分请求,但是一旦服务器并没有拒绝该请求,客户端应该继续发送其余的请求. Switching Protocols 服务器转换协议 ...
- HTTP协议—常见的HTTP响应状态码解析
常见的HTTP响应状态码解析 1XX Informational(信息性状态码) 2XX Success(成功状态码) 3XX Redirection(重定向状态码) 4XX Client Error ...
- Java Web学习总结(21)——http协议响应状态码大全以及常用状态码
http协议响应状态码大全以及常用状态码 当我们在浏览网页或是在查看服务器日志时,常会遇到3位数字的状态码,这3位数字是什么意思呢?其实,这3位数字是HTTP状态码,用来表示网页服务器HTTP响应状态 ...
- 【转】HTTP响应状态码参考簿
HTTP响应状态码参考簿 http状态返回代码 1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态代码. http状态返回代码 代码 说明100 (继续) 请求者应当继续提出请求. ...
随机推荐
- 互联网+ 何人能挡?带着你的Code飞奔吧!
Python方向: 早期方向 Web全栈 擅长专栏 爬虫系列 数据分析 人工智能 物联网系(lot万物互联)[逆天很看好未来的前景] 自动化运维(安全与测试) 其他系列 游戏开发(最近很火) 导航栏: ...
- 【学习笔记】TensorFlow
1. tf.Graph().as_default() 的作用 首先看官网上的解释: 再看博主 Joanna-In-Hdu&Hust 对此比较通俗易懂的解释(https://www.cnblog ...
- java的toString方法和sort方法
public class arrayTool { public static String toString(int arr[]){ String result = ""; for ...
- qt 视频播放器错误解决方法
DirectShowPlayerService::doRender: Unresolved error code 0x80040266 () 当你发布的qmlproject包含QtMultimedia ...
- Day055--MySQL--外键的变种,表与表的关系,单表查询,多表查询, 内连接,左右连接,全外连接
表和表的关系 ---- 外键的变种 * 一对多或多对一 多对多 一对一 参考 https://www.cnblogs.com/majj/p/9169416.html 如何找出两张表之间的关系 分析步骤 ...
- Flash设置(各种版本浏览器包括低版本IE)
涉及到的各种版本flash百度下都能下到的,不再说明. Flash的安装比较麻烦,涉及多种浏览器.多种操作系统支持,安装.设置的地方比较多,以下说明基本涉及大部分安装过程中可能遇到的问题,如果安装或视 ...
- 2019年最大的Flag
2019年最大的Flag 今天是2019/1/15 我要立一个2019年的Flag:刻意的追求优秀>>>>>>>>>>>>勿以善 ...
- 第二章,循环结构,输入输出,clock
计时 计时函数: clock() 返回目前为止运行的时间 注意要除以常数 CLOCKS_PER_SEC, 才能得到以秒为单位. 头文件 time.h 管道 在windows命令行下执行echo 20| ...
- C51学习
十六个数字循环显示 #include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar uns ...
- Linux-Shell编程之数组操作
源码 #!/bin/bash str="Array - Demo Shell"; echo ${#str} #求字符串長度 #定義 arr=('a' 'b' 'c' 'd' 'e' ...