【问题标题】:Requests - proxies dictionary请求 - 代理字典
【发布时间】:2015-07-31 19:32:18
【问题描述】:

我对@9​​87654322@ 模块有点困惑,尤其是代理

来自文档:

代理

到代理 URL 的字典映射协议(例如 {‘http’: 'foo.bar:3128'}) 用于每个请求。

字典中可以有更多的一种类型的代理吗?我的意思是可以把代理列表放在那里,requests 模块会尝试它们并只使用那些有效的吗?

或者只能有一个代理地址,例如http

【问题讨论】:

  • 看到this SO QA了吗?由此看来,一个协议可以有多个代理。试试吧!
  • 似乎只有一个代理对一种协议有效。您可能需要自己检查代理的可用性。
  • 请求中的代理非常糟糕,恕我直言......特别是如果用户在 proxyconfigfile 和其他废话后面
  • 好的,我自己试过了。显然它有效,因为字典中的多个键被覆盖,并且只考虑最后一个条目。
  • @Pynchia 所以它不起作用,是吗?我在考虑类似 'http':[ip,ip,ip..]

标签: python proxy network-programming connection python-requests


【解决方案1】:

使用proxies 参数受限于python 字典的本质(即每个键必须是唯一的)。

import requests

url = 'http://google.com'
proxies = {'https': '84.22.41.1:3128',
           'http': '185.26.183.14:80',
           'http': '178.33.230.114:3128'}

if __name__ == '__main__':
    print url
    print proxies
    response = requests.get(url, proxies=proxies)
    if response.status_code == 200:
        print response.text
    else:
        print 'Response ERROR', response.status_code

输出

http://google.com
{'http': '178.33.230.114:3128', 'https': '84.22.41.1:3128'}
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en"><head><meta content="Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for."
...more html...

如您所见,proxies 字典中的http 协议键的值对应于其分配中最后遇到的值(即178.33.230.114:3128)。尝试交换 http 条目。

所以,答案是否定的,您不能使用简单的字典为同一协议指定多个代理。

我尝试过使用可迭代对象作为值,这对我来说很有意义

proxies = {'https': '84.22.41.1:3128',
           'http': ('178.33.230.114:3128', '185.26.183.14:80', )}

但没有运气,它会产生错误

【讨论】:

  • 感谢您的回答。所以我尝试了很多代理,但似乎有一些问题。 r = requests.get('wtfismyip.com/text', proxies={'http':'52.10.202.111:8080'}) 返回我的 IP 地址,而不是这个匿名代理。
  • 您在get 电话 (;) 中有错字。几分钟前,我在我的回答中尝试了代理,它们工作正常。我从this site 得到了代理。我的回答能满足你的问题吗?
  • 哦,对不起。我没有注意到 wtfismyip 是 https 而不是 http。现在,一切正常:)
  • 是的,您的回答满足了我的问题。谢谢
  • 谢谢,感谢您的提问,我今天学到了一些新东西。 :)
【解决方案2】:

嗯,其实你可以,我用几行代码就完成了,效果很好。

import requests


class Client:

    def __init__(self):
        self._session = requests.Session()
        self.proxies = None

    def set_proxy_pool(self, proxies, auth=None, https=True):
        """Randomly choose a proxy for every GET/POST request        
        :param proxies: list of proxies, like ["ip1:port1", "ip2:port2"]
        :param auth: if proxy needs auth
        :param https: default is True, pass False if you don't need https proxy
        """
        from random import choice

        if https:
            self.proxies = [{'http': p, 'https': p} for p in proxies]
        else:
            self.proxies = [{'http': p} for p in proxies]

        def get_with_random_proxy(url, **kwargs):
            proxy = choice(self.proxies)
            kwargs['proxies'] = proxy
            if auth:
                kwargs['auth'] = auth
            return self._session.original_get(url, **kwargs)

        def post_with_random_proxy(url, *args, **kwargs):
            proxy = choice(self.proxies)
            kwargs['proxies'] = proxy
            if auth:
                kwargs['auth'] = auth
            return self._session.original_post(url, *args, **kwargs)

        self._session.original_get = self._session.get
        self._session.get = get_with_random_proxy
        self._session.original_post = self._session.post
        self._session.post = post_with_random_proxy

    def remove_proxy_pool(self):
        self.proxies = None
        self._session.get = self._session.original_get
        self._session.post = self._session.original_post
        del self._session.original_get
        del self._session.original_post

    # You can define whatever operations using self._session

我是这样使用的:

client = Client()
client.set_proxy_pool(['112.25.41.136', '180.97.29.57'])

这很简单,但实际上对我有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多