Python:如何使用请求库通过几个不同的代理服务器访问url?
正如它在标题中所说,我正试图通过几个不同的代理顺序访问url(使用for循环)。现在这是我的代码: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
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':行