Python urllib超过TOR?

OJW*_*OJW 17 python urllib2 tor socks

示例代码:

#!/usr/bin/python
import socks
import socket
import urllib2

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS4, "127.0.0.1", 9050, True)
socket.socket = socks.socksocket

print urllib2.urlopen("http://almien.co.uk/m/tools/net/ip/").read()
Run Code Online (Sandbox Code Playgroud)

TOR在端口9050上运行SOCKS代理(默认值).该请求通过TOR,在我自己以外的IP地址上显示.但是,TOR控制台会发出警告:

"2月28日22:44:26.233 [警告]你的应用程序(使用socks4到端口80)只给Tor一个IP地址.做DNS解析的应用程序本身可能泄漏信息.考虑使用Socks4A(例如通过privoxy或socat).有关详细信息,请参阅 https://wiki.torproject.org/TheOnionRouter/TorFAQ#SOCKSAndDNS."

即DNS查找不通过代理.但这就是setdefaultproxy应该做的第4个参数,对吧?

来自http://socksipy.sourceforge.net/readme.txt:

setproxy(proxytype,addr [,port [,rdns [,username [,password]]]])

rdns - 这是一个布尔标志,而不是修改DNS解析的行为.如果设置为True,则将在服务器上远程执行DNS解析.

选择PROXY_TYPE_SOCKS4和PROXY_TYPE_SOCKS5时效果相同.

它不能是本地DNS缓存(如果urllib2甚至支持它),因为当我将URL更改为此计算机以前从未访问过的域时会发生这种情况.

Gar*_*son 20

问题是httplib.HTTPConnection使用socket模块的create_connection辅助函数,它getaddrinfo在连接套接字之前通过常规方法执行DNS请求.

解决方案是在导入之前创建自己的create_connection函数并将其修补到socket模块中urllib2,就像我们对socket类一样.

import socks
import socket
def create_connection(address, timeout=None, source_address=None):
    sock = socks.socksocket()
    sock.connect(address)
    return sock

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)

# patch the socket module
socket.socket = socks.socksocket
socket.create_connection = create_connection

import urllib2

# Now you can go ahead and scrape those shady darknet .onion sites
Run Code Online (Sandbox Code Playgroud)

  • 注意:新的SOCKS端口似乎是9150.我花了一个小时,禁用防火墙等试图弄清楚为什么它没有连接... (6认同)

Wol*_*lph 5

问题是您要urllib2在建立袜子连接之前进行导入。

尝试以下方法:

import socks
import socket

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS4, '127.0.0.1', 9050, True)
socket.socket = socks.socksocket

import urllib2
print urllib2.urlopen("http://almien.co.uk/m/tools/net/ip/").read()
Run Code Online (Sandbox Code Playgroud)

手动请求示例:

进口袜子                                                         
导入urlparse                                                      

SOCKS_HOST ='本地主机'                                             
SOCKS_PORT = 9050                                                    
SOCKS_TYPE =袜子.PROXY_TYPE_SOCKS5                                 

url ='http://www.whatismyip.com/automation/n09230945.asp'           
解析= urlparse.urlparse(url)                                      


套接字= socks.socksocket()                                          
socket.setproxy(SOCKS_TYPE,SOCKS_HOST,SOCKS_PORT)                  
socket.connect((parsed.netloc,80))                                  
socket.send('''GET%(uri)s HTTP / 1.1                                  
主机:%(host)s                                                       
连接:关闭                                                    

'''%dict(                                                          
    uri = parsed.path,                                                 
    host = parsed.netloc,                                              
))                                                                   

打印socket.recv(1024)                                              
socket.close()

  • 注意:新的SOCKS端口似乎是9150。我实际上花了一个小时,禁用了防火墙等。试图弄清为什么它没有连接... (3认同)