Python:如何使用请求库通过几个不同的代理服务器访问url?

Python:如何使用请求库通过几个不同的代理服务器访问url?,python,httprequest,python-requests,Python,Httprequest,Python Requests,正如它在标题中所说,我正试图通过几个不同的代理顺序访问url(使用for循环)。现在这是我的代码: import requests import json with open('proxies.txt') as proxies: for line in proxies: proxy=json.loads(line) with open('urls.txt') as urls: for line in urls: ur

正如它在标题中所说,我正试图通过几个不同的代理顺序访问url(使用for循环)。现在这是我的代码:

import requests
import json
with open('proxies.txt') as proxies:
    for line in proxies:
        proxy=json.loads(line)
        with open('urls.txt') as urls:
        for line in urls:
            url=line.rstrip()
            data=requests.get(url, proxies={'http':line})
            data1=data.text
            print data1
和我的URL.txt文件:

http://api.exip.org/?call=ip
{"https": "84.22.41.1:3128"}
{"http":"194.126.181.47:81"}
{"http":"218.108.170.170:82"}
和my proxies.txt文件:

http://api.exip.org/?call=ip
{"https": "84.22.41.1:3128"}
{"http":"194.126.181.47:81"}
{"http":"218.108.170.170:82"}
我在[www.hidemyas.com][1]上得到的

由于某种原因,输出是

68.6.34.253
68.6.34.253
68.6.34.253
就好像它是通过我自己的路由器ip地址访问那个网站一样。换句话说,它不是试图通过我给它的代理进行访问,它只是一次又一次地循环使用我自己的代理。我做错了什么?

根据线程,您需要将
代理
字典指定为
{“协议”:“ip:port”}
,因此您的代理文件应该如下所示

{"https": "84.22.41.1.3128"}
{"http": "194.126.181.47:81"}
{"http": "218.108.170.170:82"}
编辑: 您正在对URL和代理重复使用
。可以在内部循环中重用
,但您应该使用
proxies=proxy
——您已经解析了JSON,不需要构建另一个字典。此外,正如abanert所说,您应该进行检查,以确保您请求的协议与代理的协议匹配。将代理指定为字典的原因是允许查找匹配的协议。

根据thread,您需要将
代理
字典指定为
{“协议”:“ip:port”}
,因此您的代理文件应该如下所示

{"https": "84.22.41.1.3128"}
{"http": "194.126.181.47:81"}
{"http": "218.108.170.170:82"}
编辑:
您正在对URL和代理重复使用
。可以在内部循环中重用
,但您应该使用
proxies=proxy
——您已经解析了JSON,不需要构建另一个字典。此外,正如abanert所说,您应该进行检查,以确保您请求的协议与代理的协议匹配。将代理指定为字典的原因是允许查找匹配的协议。

这里有两个明显的问题:

data=requests.get(url, proxies={'http':line})
首先,因为在代理中的行的
中有一个
for line in URL:
line
将是当前URL,而不是当前代理。此外,即使您没有重用
,它也将是JSON字符串表示,而不是您从JSON解码的dict

然后,如果您将其修复为使用
代理
,而不是像
{'https':'83.22.41.1:3128'}
,那么您将传递
{'http':{'https':'83.22.41.1:3128'}
。这显然不是一个有效的值

要解决这两个问题,只需执行以下操作:

data=requests.get(url, proxies=proxy)

同时,如果您有HTTPS URL,但当前代理是HTTP代理,会发生什么情况?你不打算使用代理。因此,您可能希望添加一些内容以跳过它们,如:

if urlparse.urlparse(url).scheme not in proxy:
    continue
client = Client()
client.set_proxy_pool(['112.25.41.136', '180.97.29.57'])

这里有两个明显的问题:

data=requests.get(url, proxies={'http':line})
首先,因为在代理中的行的
中有一个
for line in URL:
line
将是当前URL,而不是当前代理。此外,即使您没有重用
,它也将是JSON字符串表示,而不是您从JSON解码的dict

然后,如果您将其修复为使用
代理
,而不是像
{'https':'83.22.41.1:3128'}
,那么您将传递
{'http':{'https':'83.22.41.1:3128'}
。这显然不是一个有效的值

要解决这两个问题,只需执行以下操作:

data=requests.get(url, proxies=proxy)

同时,如果您有HTTPS URL,但当前代理是HTTP代理,会发生什么情况?你不打算使用代理。因此,您可能希望添加一些内容以跳过它们,如:

if urlparse.urlparse(url).scheme not in proxy:
    continue
client = Client()
client.set_proxy_pool(['112.25.41.136', '180.97.29.57'])
直接抄袭我的作品

事实上你可以,我已经用几行代码完成了这项工作,效果非常好

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
我是这样使用它的:

if urlparse.urlparse(url).scheme not in proxy:
    continue
client = Client()
client.set_proxy_pool(['112.25.41.136', '180.97.29.57'])
这很简单,但实际上对我很有用。

直接从我的作品中复制

事实上你可以,我已经用几行代码完成了这项工作,效果非常好

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
我是这样使用它的:

if urlparse.urlparse(url).scheme not in proxy:
    continue
client = Client()
client.set_proxy_pool(['112.25.41.136', '180.97.29.57'])

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

这个答案很有用,而且似乎你是对的。然而,在我修复它之后,我遇到了同样的问题。有什么想法吗?上面的应该可以解决。如果没有,请告诉我(不过要注意协议匹配点)。我测试了这个,它成功了。只需将:proxies={'http':line}替换为proxies=proxy这个答案很有用,而且似乎您是对的。然而,在我修复它之后,我遇到了同样的问题。有什么想法吗?上面的应该可以解决。如果没有,请告诉我(不过要注意协议匹配点)。我测试了这个,它成功了。只需将:proxies={'http':line}替换为proxies=proxy,正如我在前面的一个问题上所建议的那样,如果打印出传递的一些中间值,或者在调试器或交互式可视化工具中运行,或者以其他方式查看它们,您会发现理解发生了什么事情要容易得多。如果您打印出每个{code>{'http':line}
,很明显出了什么问题。为什么我要打印出每个{'http':line}?这不就是多次打印url吗?我是否应该打印网页上的html,以便验证它是否是代理服务器ip地址?如果您不知道它将打印出什么,您将了解发生了什么。如果你认为你知道它会打印出什么,你就会知道你是否正确。这是最基本的调试。很明显,脚本中的某些内容没有达到预期效果。第一步是找出问题的症结所在,唯一的方法是查看这些值,看看它们是否错了。正如我在前面的一个问题上所建议的,如果你打印出一些传递的中间值,你会发现理解发生了什么事情要容易得多,或者在调试器或交互式可视化工具中运行,或者以其他方式查看它们。如果您打印出每个
{'http':行