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 выдает предупреждение:
"28 февраля, 22:44:26.233 [предупреждение] Ваше приложение (использующее socks4 для порта 80) дает Tor только IP-адрес. Приложения, которые разрешают DNS, могут самостоятельно утекать информацию. Рассмотрите возможность использования Socks4A (например, через privoxy или socat). Для получения дополнительной информации см. https://wiki.torproject.org/TheOnionRouter/TorFAQ. "
то есть DNS-запросы не проходят через прокси. Но это то, что должен делать 4-й параметр для setdefaultproxy, верно?
С 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 на домен, который этот компьютер никогда не посещал ранее.
3 ответа
Проблема в том, что 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
Проблема в том, что вы импортируете 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()
Пример запроса вручную:
импортные носки импорт 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 хост: %(хост) s соединение: закрыть ''' % dict(= URI parsed.path, хост = parsed.netloc,)) print socket.recv (1024) socket.close ()
Я опубликовал статью с полным исходным кодом, показывающую, как использовать urllib2 + SOCKS + Tor, на http://blog.databigbang.com/distributed-scraping-with-multiple-tor-circuits/
Надеюсь, это решит ваши проблемы.