サンプルコード:
#!/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()
TORはポート9050(デフォルト)でSOCKSプロキシを実行しています。リクエストはTORを経由し、自分以外のIPアドレスで表示されます。ただし、TORコンソールは警告を出します:
"Feb 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の両方を選択しても同じ効果があります。
このコンピューターがこれまでアクセスしたことのないドメインにURLを変更すると発生するため、ローカルDNSキャッシュにすることはできません(urllib2がそれをサポートしている場合)。
問題は、httplib.HTTPConnection
がsocket
モジュールの create_connection
ヘルパー関数を使用して、接続する前に通常のgetaddrinfo
メソッドを介してDNS要求を実行することです。ソケット。
解決策は、socket
クラスの場合と同じように、create_connection
をインポートする前に、独自の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
問題は、靴下の接続を設定する前に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()
手動リクエストの例:
import socks import urlparse SOCKS_Host = 'localhost' SOCKS_PORT = 9050 SOCKS_TYPE = socks.PROXY_TYPE_SOCKS5 url = 'http://www.whatismyip.com/automation/n09230945.asp' parsed = urlparse.urlparse(url) socket = socks.socksocket() socket.setproxy(SOCKS_TYPE、SOCKS_Host、SOCKS_PORT) socket.connect((parsed.netloc、80)) socket。 send( '' 'GET%(uri)s HTTP/1.1 Host:%(Host)s connection:close '' '%dict( uri = parsed.path、 Host = parsed.netloc、 )) print socket.recv(1024) socket.close()
http://blog.databigbang.com/distributed-scraping-with-multiple-tor-circuits/ でurllib2 + SOCKS + Torの使用方法を示す完全なソースコードを含む記事を公開しました
それがあなたの問題を解決することを願っています。