Scrapy 扩展中间件: 针对特定响应状态码,使用代理重新请求

0.参考

https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#module-scrapy.downloadermiddlewares.redirect

https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#module-scrapy.downloadermiddlewares.httpproxy

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:[email protected]_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:[email protected]_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 <302 http://httpbin.org/status/302> http://httpbin.org/redirect/1
2018-07-18 18:42:43 [test] DEBUG: Will AutoProxy for <403 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

原文地址:https://www.cnblogs.com/my8100/p/scrapy_middleware_autoproxy.html

时间: 2024-10-10 03:04:37

Scrapy 扩展中间件: 针对特定响应状态码,使用代理重新请求的相关文章

9. http协议_响应状态码_页面渲染流程_路由_中间件

1. http协议 超文本传输协议 协议详细规定了 浏览器 和 万维网服务器 之间互相通信的规则 客户端与服务端通信时传输的内容我们称之为报文(请求报文.响应报文) 常见的发送 get 请求方式 在浏览器地址栏输入 url 地址访问 所有的标签默认发送的是 get 请求:如 script link img a... form 表单默认也是 get 请求 常见的发送 post 请求方式 只能通过 form 表单,设置 method="post" 发送 ajax 可以发送任意请求 2. 响

TCP/IP协议族(一) HTTP简介、请求方法与响应状态码

接下来想系统的回顾一下TCP/IP协议族的相关东西,当然这些东西大部分是在大学的时候学过的,但是那句话,基础的东西还是要不时的回顾回顾的.接下来的几篇博客都是关于TCP/IP协议族的,本篇博客就先简单的聊一下TCP/IP协议族,然后聊一下HTTP协议,然后再聊一下SSL上的HTTP(也就是HTTPS)了.当然TCP/IP协议族是个老生常谈的话题,网络上关于该内容的文章一抓一大把呢,但是鉴于其重要性,还是有必要系统的总结一下的. 一.TCP/IP协议组简述 在聊HTTP与HTTPS之前呢,我们先简

SIP响应状态码

SIP响应状态码 类型 状态码 状态说明 详解 临时应答 (1XX) 100 Trying 正在处理中 这个应答表示下一个节点的服务器已经接收到了这个请求并且还没有执行这个请求的特定动作(比如,正在打开数据库的时候).这个应答,就像其他临时应答一 样,种植了UAC重新传送INVITE请求.100(Trying)应答和其他临时应答不同的是,在这里,它永远不会被有状态proxy转发到上行流中.  180 Ringing 振铃 UA收到INVITE请求并且试图提示给用户.这个应答应当初始化一个本地回铃

HTTP响应状态码

常见的http响应状态码 http状态返回代码 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码 100    (继续) 请求者应当继续提出请求 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分 101   (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换 http状态返回代码 2xx (成功) 表示成功处理了请求的状态代码 200   (成功)    服务器已成功处理了请求 通常,这表示服务器提供了请求的网页201   (已创建)  请求成功并且服务

HTTP/NSURLConnection(请求、响应)、http响应状态码大全

一.网络基础 1.基本概念> 为什么要学习网络编程在移动互联网时代,移动应用的特征有几乎所有应用都需要用到网络,比如QQ.微博.网易新闻.优酷.百度地图只有通过网络跟外界进行数据交互.数据更新,应用才能保持新鲜.活力如果没有了网络,也就缺少了数据变化,无论外观多么华丽,终将变成一潭死水 移动网络应用 = 良好的UI + 良好的用户体验 + 实时更新的数据新闻:网易新闻.新浪新闻.搜狐新闻.腾讯新闻视频:优酷.百度视频.搜狐视频.爱奇艺视频音乐:QQ音乐.百度音乐.酷狗音乐.酷我音乐LBS:百度地

http响应状态码大全

http响应状态码大全 转:http://blog.sina.com.cn/s/blog_4ae187490100x9u7.html http状态返回代码 1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态代码. http状态返回代码 代码   说明100   (继续) 请求者应当继续提出请求. 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分. 101   (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换. http状态返回代码 2xx (成功)表示成功处理

前端 http协议 四大特性 web本质 -响应状态码 列表标签 表单操作 form表单 # 44

1.前端简介 1 """""" 2 """前端:""" 3 """和python没有任何关系""" 4 5 1.什么是前端? 6 任何与用户直接打交道的操作界面都可以称之为前端 7 比如 : 电脑界面 手机界面 平板界面 8 9 2.什么是后端? 10 暂时先理解成,幕后操作者 11 不直接与用户打交道 12 13 3.为什么要

HTTP request/respond详解及响应状态码

一.http request 详解(客户端告诉服务端) 一个http请求指从客户端到服务器的请求消息,可以通过浏览器F12键,可以看到以下信息: 1.请求地址:url 2.请求方法:head.get‘.post.put.options.delete.patch 3.http协议/版本:可以打开浏览器f12仔细看 4.请求头 5.请求参数 二.HTTP respond 详解(服务端告诉客户端) 一个http respond (http响应) 只得是从服务端到客户端的响应消息 1.响应状态码 2.响

Http常见响应状态码

HTTP响应状态码: 1xx:信息 100 Continue 服务器仅接收到部分请求,但是一旦服务器并没有拒绝该请求,客户端应该继续发送其余的请求. 101 Switching Protocols 服务器转换协议:服务器将遵从客户的请求转换到另外一种协议. 2xx:成功 200 OK 请求成功(其后是对GET和POST请求的应答文档) 201 Created 请求被创建完成,同时新的资源被创建. 202 Accepted 供处理的请求已被接受,但是处理未完成. 203 Non-authorita