我管理了很多HTTPS代理(那些拥有自己SSL连接的代理)。我在python中构建一个诊断工具,试图通过每个代理连接到一个页面,如果它不能通过其中一个代理连接我,请给我发电子邮件。
我已经着手解决此问题的方法是使用urllib连接每个代理并返回一个页面,该页面应该说成功"成功"使用下面的代码。
def fetch(url):
connection = urllib.urlopen(
url,
proxies={'http':"https://"+server+':443'}
)
return connection.read()
print fetch(testURL)
这会抓取我想要的页面完全问题是它仍然会获取我想要的页面,即使代理服务器信息不正确或代理服务器处于非活动状态。因此要么它从不使用代理服务器,要么尝试它并在它失败时连接它。
我该如何纠正?
编辑:似乎没有人知道如何做到这一点。我将开始阅读其他语言库,看看他们是否能更好地处理它。有没有人知道在Go等其他语言中它是否更容易?
编辑:我刚刚在下面的评论中写了这个,但我认为这可能是一个误解。 "代理拥有自己的ssl连接。因此,如果我去google.com,我首先与foo.com进行密钥交换,然后再使用目的地址bar.com或目的地地址baz.com进行密钥交换。目的地不必是https,代理是https"
答案 0 :(得分:3)
大多数人都将https代理理解为理解CONNECT请求的代理。我的例子创建了直接的ssl连接。
try:
import http.client as httplib # for python 3.2+
except ImportError:
import httplib # for python 2.7
con = httplib.HTTPSConnection('proxy', 443) # create proxy connection
# download http://example.com/ through proxy
con.putrequest('GET', 'http://example.com/', skip_host=True)
con.putheader('Host', 'example.com')
con.endheaders()
res = con.getresponse()
print(res.read())
如果您的代理是反向代理,请更改
con.putrequest('GET', 'http://example.com/', skip_host=True)
到
con.putrequest('GET', '/', skip_host=True)`
答案 1 :(得分:1)
我认为它不适用于https请求。它是否正确?如果是,那么上面的代码仅为http定义代理。尝试将其添加到https:
proxies={'https':"https://"+server+':443'}
另一种选择是使用requests
python模块而不是urllib
。看看http://docs.python-requests.org/en/latest/user/advanced/#proxies
答案 2 :(得分:1)
urllib似乎不支持这一点,并且不清楚urllib2是否支持。但是,如果只使用curl(或curllib),那通常是最常见的HTTP客户端api(虽然更复杂,这就是urllib等出现的原因)。
查看命令行curl
工具,似乎很有希望:
-x, --proxy <[protocol://][user:password@]proxyhost[:port]>
Use the specified HTTP proxy. If the port number is not specified, it is assumed at port 1080.
This option overrides existing environment variables that set the proxy to use. If there's an environment variable setting a proxy, you can set
proxy to "" to override it.
All operations that are performed over an HTTP proxy will transparently be converted to HTTP. It means that certain protocol specific operations
might not be available. This is not the case if you can tunnel through the proxy, as one with the -p, --proxytunnel option.
User and password that might be provided in the proxy string are URL decoded by curl. This allows you to pass in special characters such as @ by
using %40 or pass in a colon with %3a.
The proxy host can be specified the exact same way as the proxy environment variables, including the protocol prefix (http://) and the embedded
user + password.
From 7.21.7, the proxy string may be specified with a protocol:// prefix to specify alternative proxy protocols. Use socks4://, socks4a://,
socks5:// or socks5h:// to request the specific SOCKS version to be used. No protocol specified, http:// and all others will be treated as HTTP
proxies.
If this option is used several times, the last one will be used.
答案 3 :(得分:0)
使用超时怎么样?如果代理在30秒内未能连接,则应注意未连接。
def fetch(url, server):
proxy_handler = urllib2.ProxyHandler({'http':'https://'+server+':443'})
opener = urllib2.build_opener(proxy_handler, urllib2.HTTPHandler(debuglevel=0))
urllib2.install_opener(opener)
try:
response = opener.open( url, timeout = 30)
return response.read()
except:
print "Can't connect with proxy %s" % (server)
print fetch(url,serverIp)
您可以更改debuglevel = 1
以查看连接详情
我将它用于全局代理,并且我的互联网连接30秒是最大超时,以确定我是否连接。在我的测试中,如果连接时间超过30秒,则总是失败。