使用动态代理IP返回Response [407]

代理返回Response [407]


快代理工程师小哥在进行技术支持&工单处理的过程中经常会遇到一些用户有相同的问题。所以我们准备将一些在使用快代理产品中的一些经典问题进行经验总结,帮助到更多人使用代理IP。本文所有内容均来自快代理工程师真实的客户技术支持。

客户问题

使用产品类型:

私密代理集中提取
在这里插入图片描述

问题描述:

程序运行的过程中总是有少部分请求拿不到任何响应,服务器没有任何响应,现象和最开始没有使用用户名密码一样。怀疑是快代理的代理IP用户认证是有问题的。

技术支持流程

0x01 排除产品问题
首先还是老样子,工程师编写脚本使用用户订单下的代理IP,运行了一段时间后问题并没有出现407 Proxy Authentication Required的情况。

0x02 询问代码&分析问题
但是用户这边是拿出了详细的程序运行日志,统计确实是存在没有任何响应的数据记录,于是我们向用户要来了代码。粗略查看后,用户是使用Python的Requests框架配合多线程进行了二次封装。经过一段时间的调试与排查,我在Requests的返回值里面发现了蹊跷:用户对于每次请求的response都会进行一次布尔运算。

代码如下:

#!/usr/bin/python
# coding:utf-8
import requests
r = None
proxy_ip = "39.97.170.201:16818"
proxies = {
    "http": "http://%(proxy)s/" % {"proxy": proxy_ip},
    "https": "http://%(proxy)s/" % {"proxy": proxy_ip}
}
try:
    r = requests.get("http://www.baidu.com/", proxies=proxies)
    print r
except Exception, e:
    print e
if r:
    print "True"
else:
    print "False"
<Response [407]>
False

使用一台没有配置白名单IP的电脑,填写上代理IP运行此程序你会发现:

为什么没有输出True?按照常理来说,程序运行并没有出现异常,r此时是请求完成后的返回值,只要返回值不是零值就能够匹配到True的。但是为什么返回的<Response [407]>就会引发if判断异常呢?

> type(r)
> requests.models.Response

查看Requests关于Response代码:
•Response对象含有了__bool__魔法方法的处理,对象进行布尔运算时,这个魔法函数会被调用。
•Response对象的布尔值取决于self.ok。
•在HTTP状态码为400-500或者是500-600的范围内时,self.ok都为False,其余为True。

class Response(object):
    """The :class:`Response <Response>` object, which contains a
    server's response to an HTTP request.
    """
    __attrs__ = [
        '_content', 'status_code', 'headers', 'url', 'history',
        'encoding', 'reason', 'cookies', 'elapsed', 'request'
    ]
    def __init__(self):
        self._content = False
        self._content_consumed = False
        self._next = None
        #: Integer Code of responded HTTP Status, e.g. 404 or 200.
        self.status_code = None
        
    def __repr__(self):
        return '<Response [%s]>' % (self.status_code)
    def __bool__(self):
        """Returns True if :attr:`status_code` is less than 400.
        This attribute checks if the status code of the response is between
        400 and 600 to see if there was a client error or a server error. If
        the status code, is between 200 and 400, this will return True. This
        is **not** a check to see if the response code is ``200 OK``.
        """
        return self.ok


    @property
    def ok(self):
        """Returns True if :attr:`status_code` is less than 400, False if not.
        This attribute checks if the status code of the response is between
        400 and 600 to see if there was a client error or a server error. If
        the status code is between 200 and 400, this will return True. This
        is **not** a check to see if the response code is ``200 OK``.
        """
        try:
            self.raise_for_status()
        except HTTPError:
            return False
        return True
      
    def raise_for_status(self):
        """Raises :class:`HTTPError`, if one occurred."""
        http_error_msg = ''
        if isinstance(self.reason, bytes):
            # We attempt to decode utf-8 first because some servers
            # choose to localize their reason strings. If the string
            # isn't utf-8, we fall back to iso-8859-1 for all other
            # encodings. (See PR #3538)
            try:
                reason = self.reason.decode('utf-8')
            except UnicodeDecodeError:
                reason = self.reason.decode('iso-8859-1')
        else:
            reason = self.reason
        if 400 <= self.status_code < 500:
            http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url)
        elif 500 <= self.status_code < 600:
            http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url)
        if http_error_msg:
            raise HTTPError(http_error_msg, response=self)
            
        ......      

结论

用户最初没有使用用户名密码进行认证时,代理返回<Response [407]>,随后用户带上了用户名密码,程序正常跑起来。

但是访问的URL中有一部分失效链接或者当时目标网站不稳定等等其他因素,拿到了<Response [404]>,<Response [502]>这样的状态码。

由于Requests框架对与400-600状态码响应进行布尔操作都会返回False,跟之前代理未认证返回的<Response [407]>出现的现象一样,于是误以为是快代理的代理IP出现了问题。

在和用户解释了原因后,用户随即修改代码,通过HTTP状态码来判断代理请求是否成功,完美解决了这个问题。

获取更多经验好文
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值