将 urllib2 与 SOCKS 代理一起使用
Posted
技术标签:
【中文标题】将 urllib2 与 SOCKS 代理一起使用【英文标题】:Using urllib2 with SOCKS proxy 【发布时间】:2010-03-29 12:17:38 【问题描述】:是否可以通过每个 opener basic 的一个 socks 服务器上的 SOCKS 代理获取带有 urllib2 的页面?我已经看到了使用 setdefaultproxy 方法的解决方案,但是我需要在不同的开瓶器中使用不同的袜子。
所以有 SocksiPy 库,效果很好,但必须这样使用:
import socks
import socket
socket.socket = socks.socksocket
import urllib2
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "x.x.x.x", y)
也就是说,它为所有 urllib2 请求设置相同的代理。如何为不同的开启者设置不同的代理?
【问题讨论】:
【参考方案1】:试试pycurl:
import pycurl
c1 = pycurl.Curl()
c1.setopt(pycurl.URL, 'http://www.google.com')
c1.setopt(pycurl.PROXY, 'localhost')
c1.setopt(pycurl.PROXYPORT, 8080)
c1.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5)
c2 = pycurl.Curl()
c2.setopt(pycurl.URL, 'http://www.yahoo.com')
c2.setopt(pycurl.PROXY, 'localhost')
c2.setopt(pycurl.PROXYPORT, 8081)
c2.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5)
c1.perform()
c2.perform()
【讨论】:
哇,多么好的pythonic API! ://【参考方案2】:是的,你可以。我在How can I use a SOCKS 4/5 proxy with urllib2? 上重复我的回答 您需要像使用 http 代理一样为每个代理创建一个开启程序。将这个功能添加到 SocksiPy 的代码可以在 GitHub https://gist.github.com/869791 中找到,简单如下:
opener = urllib2.build_opener(SocksiPyHandler(socks.PROXY_TYPE_SOCKS4, 'localhost', 9999))
print opener.open('http://www.whatismyip.com/automation/n09230945.asp').read()
有关更多信息,我编写了一个运行多个 Tor 实例以表现得像一个旋转代理的示例:Distributed Scraping With Multiple Tor Circuits
【讨论】:
【参考方案3】:您只有一个用于所有开启程序的套接字,并且实现袜子是在套接字级别。所以,你不能。 我建议你使用 pycurl 库,它更灵活。
【讨论】:
是在windows上使用2.6的pycurl的简单方法吗? 不,看起来项目已经死了(上次更新是 2 年前)并且它不能在带有新 curl 的 Windows 上编译 不,(...)它不能在带有新 curl 的 Windows 上编译 用较新版本的 curl 编译 pycurl 与在较新版本的 Python 中使用 pycurl 有何关系?【参考方案4】:== EDIT ==(旧的 HTTP 代理示例在这里..)
我的错.. urllib2 没有对 SOCKS 代理的内置支持..
有一些“hacks”将 SOCKS 添加到 urllib2(或一般的套接字对象)here。 但我几乎不怀疑这将与您需要的多个代理一起使用。
只要你不想挂钩/子类 urllib2.ProxyHandler,我建议使用 pycurl。
【讨论】:
它不起作用。 urllib2.URLError:如果一次建立的连接不多,并且您需要从多个线程访问,您也许可以使用线程锁:
import socks
import socket
import thread
lock = thread.allocate_lock()
socket.socket = socks.socksocket
def GetConn():
lock.acquire()
import urllib2
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "x.x.x.x", y)
conn = urllib2.urlopen(ARGUMENTS HERE)
lock.release()
return conn
你也可以在每次需要连接时使用类似的东西:
urllib2 = execfile('urllib2.py')
urllib2.socket = dummy_class() # dummy_class needs the socket module's methods
这些显然不是很好的解决方案,但无论如何我已经投入了 2 美分 :-)
【讨论】:
【参考方案6】:使用 SOCKS 代理的一个麻烦但可行的解决方案是使用代理链设置 provixy,然后通过系统变量或任何其他方式设置 privoxy 提供的 HTTP_PROXY。
【讨论】:
【参考方案7】:您可以通过以下格式设置环境变量 HTTP_PROXY 来做到这一点:
用户:pass@proxy:端口
或者如果你使用bat/cmd,在调用脚本之前添加:
设置 HTTP_PROXY=user:pass@proxy:port
我正在使用这样的 cmd 文件使 easy_install 在代理下工作。
【讨论】:
这适用于 HTTP 代理,而不是 SOCKS 代理。 而且它不能解决每个连接单独代理的问题。以上是关于将 urllib2 与 SOCKS 代理一起使用的主要内容,如果未能解决你的问题,请参考以下文章
使用 urllib2、socks5 代理和 socksipy 时超时不起作用