Selenium WebDriver + Tor as proxy with Stem?

2019-03-29 20:37发布

问题:

I need to confirm If Stem can be used to launch a Tor process that exposes 127.0.0.1:port, then use it on selenium scripts as proxy (SOCKS).

I'm using Python 3.4.2 , Stem 1.3.0, and Tor (tor-win32-tor-0.2.5.10 expert bundle) on Windows.

This piece of code works with a standard SOCKS proxy.

from selenium import webdriver
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

profile = FirefoxProfile()
profile.set_preference('network.proxy.type', 1)
profile.set_preference('network.proxy.socks', '127.0.0.1')
profile.set_preference('network.proxy.socks_port', 9000)

driver = webdriver.Firefox(profile)
driver.implicitly_wait(30)
driver.get('http://www.reddit.com')

But I can't manage to get it working with Tor as my proxy. I tried to create a Tor process, and its created. But I don't really know If it's working properly. I don't get errors in my tor_error_log.txt

# File: stem_process.py
import stem.process
import stem

stem.process.launch_tor_with_config(
  config = {
    'SocksPort': '9000',
    'ControlPort': '9051',
    'ExitNodes': '{us}',
    'Log': [
      'NOTICE stdout',
      'ERR file c:\\tor-win32-tor-0.2.5.10\\Tor\\tor_error_log.txt',
    ],
  },
  tor_cmd = 'C:\\tor-win32-tor-0.2.5.10\\Tor\\tor.exe',
)

Then I tried two ways to create the connection or authenticate. The first one is using with and stem.control.controller. And the second at lower level with stem.socket and stem.connection

The first one:

# File: stem_test1.py
from stem.control import Controller

with Controller.from_port(address='127.0.0.1', port=9051) as controller: #port = 9051
  controller.authenticate()

  print("Tor is running version %s" % controller.get_version())

'''
# Output:
Tor is running version 0.2.5.10 (git-13318a95ddfbbf8d)
'''

The second one:

# File: stem_test2.py
import sys
import stem
import stem.connection
import stem.socket

if __name__ == '__main__':
  try:
    control_socket = stem.socket.ControlPort(port = 9051)
    stem.connection.authenticate(control_socket)
  except stem.SocketError as exc:
    print('Unable to connect to tor on port 9051: %s' % exc)
    sys.exit(1)
  except stem.connection.AuthenticationFailure as exc:
    print('Unable to authenticate: %s' % exc)
    sys.exit(1)

  print("Issuing 'GETINFO version' query...\n")
  control_socket.send('GETINFO version')
  print(control_socket.recv())

'''
# Output:
Issuing 'GETINFO version' query...

version=0.2.5.10 (git-13318a95ddfbbf8d)
OK
'''

And both run without errors... But when I use the code to call the Firefox WebDriver instance with 127.0.0.1:9000 as proxy (also tried with 127.0.0.1:9051, because I don't really know the difference between socksPort and controlPort) It doesn't work.

回答1:

Stem can't create a tor process, its only a library for connecting to an existing tor server for inspection/control via the control port.

To create the tor process itself, you need to have your system start it up with upstart/launchctl/etc. Alternatively, you can just type tor from the commandline if its installed and it'll run in the foreground.

With that, to use stem you'll need to edit your torrc to a. enable the ControlPort, and b. set an authentication method (cookieauth or hashed password stored in your torrc). The default tor SocksPort is 9050 and ControlPort is 9051.

The SocksPort is the one you route your traffic (i.e. firefox) through, the ControlPort is what you connect stem to. Mind you, only if you even need stem, since it just seems like you're trying to start a tor instance with it (and thats not do-able), if you get it running on your system vanilla, it'll work with selenium/firefox as you've got it configured (well, default port is 9050 not 9000)