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/

Надеюсь, это решит ваши проблемы.

Другие вопросы по тегам