Исключение сценария Python с Tor - PullRequest
5 голосов
/ 29 марта 2012

У меня есть следующий скрипт, который использует SocksiPY

и Tor:

from TorCtl import TorCtl

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

import urllib2
import sqlite3
from BeautifulSoup import BeautifulSoup

def newId():
    conn = TorCtl.connect(controlAddr="127.0.0.1", controlPort=9051, passphrase="123")
    TorCtl.Connection.send_signal(conn, "NEWNYM")

newId()

print(urllib2.urlopen("http://www.ifconfig.me/ip").read())

Этот код должен изменить идентификатор Tor, но он ждет некоторое время и выдает следующую ошибку:

tuple index out of range
Traceback (most recent call last):
  File "template.py", line 16, in <module>
    newId()
  File "template.py", line 14, in newId
    TorCtl.Connection.send_signal(conn, "NEWNYM")
TypeError: unbound method send_signal() must be called with Connection instance as first argument (got NoneType instance instead)

Но вышеприведенный скрипт делится на 2 отдельных скрипта:

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

import urllib2
import sqlite3
from BeautifulSoup import BeautifulSoup

print(urllib2.urlopen("http://www.ifconfig.me/ip").read())

И

from TorCtl import TorCtl
def newId():
    conn = TorCtl.connect(controlAddr="127.0.0.1", controlPort=9051, passphrase="123")
    TorCtl.Connection.send_signal(conn, "NEWNYM")

newId()

Когда вызывается второй скрипт, тогда вызывается первый, это нормально. Может кто-нибудь объяснить, в чем проблема и как ее исправить?

Ответы [ 2 ]

5 голосов
/ 17 апреля 2012

Anonymous очень хорошо объяснили перезапись этого сокета, ответ почти идеален, за исключением того, что вам нужно закрыть сокет управления .Это безопаснее из-за цикла событий TorCtl, но я должен заглянуть глубже в код TorCtl, чтобы понять этот цикл событий.

Подводя итог, ваш код становится:

from TorCtl import TorCtl

import socks
import socket
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)

import urllib2
import sqlite3
from BeautifulSoup import BeautifulSoup

__originalSocket = socket.socket

def newId():
    ''' Clean circuit switcher

    Restores socket to original system value.
    Calls TOR control socket and closes it
    Replaces system socket with socksified socket
    '''
    socket.socket = __originalSocket
    conn = TorCtl.connect(controlAddr="127.0.0.1", controlPort=9051, passphrase="123")
    TorCtl.Connection.send_signal(conn, "NEWNYM")
    conn.close()
    socket.socket = socks.socksocket

newId()

print(urllib2.urlopen("http://www.ifconfig.me/ip").read())
2 голосов
/ 14 апреля 2012

Соединение с портом управления завершается неудачно, и conn присваивается значение, которое сокеты Python используют для обозначения сбоя (который, очевидно, имеет тип NoneType).

Причина в том, что в оператореsocket.socket = socks.socksocket, очевидно, вы заменяете объект или класс сокета по умолчанию на объект, который прозрачно проксирует все через Tor, что заставляет программу пытаться прокси подключить ваш порт управления.

Решение состоит только в выполнении socket.socket = socks.socksocket после вы открыли управляющее соединение (и сохраните это соединение, если оно понадобится вам позже) или сохраните исходное значение socket.socket, чтобы при необходимости переключаться между значениями.

...