Python urllib над TOR?
Пример кода:
#!/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 запускает прокси SOCKS на порту 9050 (по умолчанию). Запрос проходит через TOR, всплывая по IP-адресу, отличному от моего. Однако консоль TOR выдает предупреждение:
"Feb 28 22: 44: 26.233 [warn] Ваш приложение (с использованием socks4 до порта 80) дает Tor только IP-адрес. Приложения, разрешающие DNS сами могут утечка информации. Рассмотрите возможность использования Socks4A (например, через privoxy или socat). Для большего информации, см. https://wiki.torproject.org/TheOnionRouter/TorFAQ#SOCKSAndDNS.
то есть. DNS-запросы не проходят через прокси-сервер. Но то, что должен сделать 4-й параметр setdefaultproxy, не так ли?
Из http://socksipy.sourceforge.net/readme.txt:
setproxy (proxytype, addr [, port [, rdns [, username [, password]]]])
rdns - это логический флаг, чем изменяет поведение DNS разрешения. Если для него установлено значение Истина, DNS разрешение будет выполнено заранее, на сервере.
Тот же эффект с выбранными PROXY_TYPE_SOCKS4 и PROXY_TYPE_SOCKS5.
Он не может быть локальным DNS-кешем (если urllib2 даже поддерживает это), потому что это происходит, когда я изменяю URL-адрес домена, который этот компьютер никогда не посещал раньше.
Ответы
Ответ 1
Проблема заключается в том, что httplib.HTTPConnection
использует вспомогательную функцию socket
create_connection
, которая выполняет запрос DNS с помощью обычного метода getaddrinfo
перед подключением сокет.
Решение состоит в том, чтобы сделать вашу собственную функцию 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
Ответ 2
Проблема заключается в том, что вы импортируете 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()
Ответ 3
Я опубликовал статью с полным исходным кодом, показывающим, как использовать urllib2 + SOCKS + Tor на http://blog.databigbang.com/distributed-scraping-with-multiple-tor-circuits/
Надеюсь, что он решает ваши проблемы.