Как управлять tor при использовании прокси-сервера tor

Я пытаюсь подключиться к ресурсу с помощью tor, меняя личность. Но после первого подключения попытка смены личности вызывает ошибку. Код:

import urllib2, socks, socket
from stem import Signal
from stem.control import Controller


def newI():
    with Controller.from_port(port=9051) as controller:
        controller.authenticate()
        controller.signal(Signal.NEWNYM)

newI()

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

headers = {'User-Agent': 'Mozilla/3.0 (x86 [en] Windows NT 5.1; Sun)'} 
req = urllib2.Request('https://google.com', None, headers)
response = urllib2.urlopen(req)
html = response.read()

newI()

Я получаю ошибку:

  File "/media/all/Run/e/c.py", line 21, in <module>
    newI()
  File "/media/all/Run/e/c.py", line 7, in newI
    with Controller.from_port(port=9051) as controller:
  File "/usr/local/lib/python2.7/dist-packages/stem/control.py", line 659, in from_port
    control_port = stem.socket.ControlPort(address, port)
  File "/usr/local/lib/python2.7/dist-packages/stem/socket.py", line 314, in __init__
    self.connect()
  File "/usr/local/lib/python2.7/dist-packages/stem/socket.py", line 187, in connect
    self._socket = self._make_socket()
  File "/usr/local/lib/python2.7/dist-packages/stem/socket.py", line 340, in _make_socket
    control_socket.connect((self._control_addr, self._control_port))
  File "/usr/lib/python2.7/dist-packages/socks.py", line 369, in connect
    self.__negotiatesocks5(destpair[0],destpair[1])
  File "/usr/lib/python2.7/dist-packages/socks.py", line 236, in __negotiatesocks5
    raise Socks5Error(ord(resp[1]),_generalerrors[ord(resp[1])])
TypeError: __init__() takes exactly 2 arguments (3 given)

Может мне нужно отключить прокси. Подскажите, как правильно это сделать.

UPD:

С pycurl это работает:

import pycurl
import cStringIO
from stem import Signal
from stem.control import Controller


def newI():
    with Controller.from_port(port=9051) as controller:
        controller.authenticate()
        controller.signal(Signal.NEWNYM)

newI()

buf = cStringIO.StringIO()
c = pycurl.Curl()
c.setopt(pycurl.URL, 'http://google.com/')
c.setopt(c.WRITEFUNCTION, buf.write)
c.setopt(pycurl.PROXY, 'localhost')
c.setopt(pycurl.PROXYPORT, 9050)
c.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5)
c.perform()
html = buf.getvalue()[7:]
buf.close()

newI()

person user2503536    schedule 30.11.2013    source источник


Ответы (2)


Проблема вызвана строкой socket.socket = socks.socksocket.

В качестве временного решения можно сохранить резервную копию socket.socket и использовать ее для отключения прокси-сервера перед запросом у Tor нового идентификатора, а затем снова настроить прокси.

Код будет выглядеть так:

import urllib2, socks, socket
from stem import Signal
from stem.control import Controller

old_socket = socket.socket
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)
socket.socket = socks.socksocket

def newI():
    socket.socket = old_socket  # don't use proxy
    with Controller.from_port(port=9051) as controller:
        controller.authenticate()
        controller.signal(Signal.NEWNYM)
    # set up the proxy again
    socket.socket = socks.socksocket

newI()

headers = {'User-Agent': 'Mozilla/3.0 (x86 [en] Windows NT 5.1; Sun)'} 
req = urllib2.Request('https://google.com', None, headers)
response = urllib2.urlopen(req)
html = response.read()

newI()

Однако я все еще жду, когда кто-нибудь опубликует объяснение того, почему возникает ошибка, и лучший способ ее исправить.

person Ionut Hulub    schedule 06.08.2014

Интересный. Интересно, если...

socket.socket = socks.socksocket

приводит к тому, что _make_socket() получает нестандартный сокет и, в свою очередь, большую часть. Если вместо этого вы используете PycURL?

person Damian    schedule 30.11.2013
comment
На самом деле это не отвечает на вопрос, поскольку использование PycURL не всегда возможно. Например, мне нужно использовать socket.socket напрямую, поэтому вместо этого я не могу использовать PycURL. - person Ionut Hulub; 13.08.2014