Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
347 views
in Technique[技术] by (71.8m points)

python - How to control tor, when use tor proxy

I'm trying to connect to a resource using a tor, changing identity. But after the first connection attempt to change identity causes an error. Code:

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()

I get error:

  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)

Maybe I need to disable the proxy. Tell me how to do it correctly.

UPD:

With pycurl it's work:

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()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is caused by the socket.socket = socks.socksocket line.

As a temporary solution, one can keep a backup copy of socket.socket and use that to unset the proxy before asking Tor for a new identity, then set up the proxy again.

The code will look like this:

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()

However, I am still waiting for someone to post an explanation as to why the error occurs, and a better way to fix it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...