32

Is it possible to make selenium use the TOR browser? Does anyone have any code they could copy-paste?

user1907403
  • 361
  • 1
  • 4
  • 3
  • 2
    It seem to be possible, see http://bolbolkod.wordpress.com/2013/02/07/selenium-with-torfirefox-mac/ – Mihai8 Mar 09 '13 at 21:52
  • I saw that too, but I was having trouble getting it to work. Looks like it was a combination of issues - Yahoo.com was refusing proxy connections (http://whatismyipaddress.com/ does not). Also, the port in the vidalia settings menu is different from what is on the tor browser. I copied the tor browser's port number and that got it to work. Sorry if this is obvious - total beginner! – user1907403 Mar 09 '13 at 22:09
  • 1
    I also think you need to open the tor browser ahead of time - or at least just vidalia so that you have a connection to the proxy – user1907403 Mar 09 '13 at 22:10
  • No need to make it work with Vidalia, neither the Tor Browser: this code simply works with your regular Firefox once you get the command line "tor" installed and running as described. That was probably the reason you needed a different port number when trying to use this code with Vidalia since the command line Tor uses a different port. – ali May 08 '13 at 01:06

12 Answers12

16

Don't use the TBB, just set the correct proxy settings in whatever browser you're using. In FF for example, like this:

#set some privacy settings
ff_prof.set_preference( "places.history.enabled", False )
ff_prof.set_preference( "privacy.clearOnShutdown.offlineApps", True )
ff_prof.set_preference( "privacy.clearOnShutdown.passwords", True )
ff_prof.set_preference( "privacy.clearOnShutdown.siteSettings", True )
ff_prof.set_preference( "privacy.sanitize.sanitizeOnShutdown", True )
ff_prof.set_preference( "signon.rememberSignons", False )
ff_prof.set_preference( "network.cookie.lifetimePolicy", 2 )
ff_prof.set_preference( "network.dns.disablePrefetch", True )
ff_prof.set_preference( "network.http.sendRefererHeader", 0 )

#set socks proxy
ff_prof.set_preference( "network.proxy.type", 1 )
ff_prof.set_preference( "network.proxy.socks_version", 5 )
ff_prof.set_preference( "network.proxy.socks", '127.0.0.1' )
ff_prof.set_preference( "network.proxy.socks_port", 9050 )
ff_prof.set_preference( "network.proxy.socks_remote_dns", True )

#if you're really hardcore about your security
#js can be used to reveal your true i.p.
ff_prof.set_preference( "javascript.enabled", False )

#get a huge speed increase by not downloading images
ff_prof.set_preference( "permissions.default.image", 2 )

##
# programmatically start tor (in windows environment)
##
tor_path = "C:\\this\\is\\the\\location\\of\\" #tor.exe
torrc_path = "C:\\you\\need\\to\\create\\this\\file\\torrc"

DETACHED_PROCESS = 0x00000008
#calling as a detached_process means the program will not die with your python program - you will need to manually kill it
##
# somebody please let me know if there's a way to make this a child process that automatically dies (in windows)
##
tor_process = subprocess.Popen( '"' + tor_path+'tor.exe" --nt-service "-f" "' + torrc_path + '"', creationflags=DETACHED_PROCESS )

#attach to tor controller
## imports ##
# import stem.socket
# import stem.connection
# import stem.Signal
##
tor_controller = stem.socket.ControlPort( port=9051 )

control_password = 'password'
#in your torrc, you need to store the hashed version of 'password' which you can get with: subprocess.call( '"' + tor_path+'tor.exe" --hash-password %s' %control_password )

stem.connection.authenticate( tor_controller, password=control_password )

#check that everything is good with your tor_process by checking bootstrap status
tor_controller.send( 'GETINFO status/bootstrap-phase' )
response = worker.tor_controller.recv()
response = response.content()

#I will leave handling of response status to you
sam-6174
  • 3,104
  • 1
  • 33
  • 34
  • 6
    Then what's the point in Tor? You could've used any of the faster anonymous proxies then. Using the whole TBB is important. – polkovnikov.ph Apr 09 '17 at 01:56
14

Yes, it is possible to make selenium use the TOR browser.

I was able to do so on both Ubuntu and Mac OS X.

Two things have to happen:

  1. Set the binary path to the firefox binary that Tor uses. On a Mac this path would typically be /Applications/TorBrowser.app/Contents/MacOS/firefox. On my Ubuntu machine it is /usr/bin/tor-browser/Browser/firefox.

  2. The Tor browser uses a SOCKS host at 127.0.0.1:9150 either through Vidalia or Tor installation. Launch Tor once from the Finder and leave it open so that Vidalia will be running. The instances launched with selenium will use the SOCKS host that Vidalia starts, too.

Here is the code to accomplish those two things. I run this on Mac OS X Yosemite:

import os
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
from selenium import webdriver


# path to the firefox binary inside the Tor package
binary = '/Applications/TorBrowser.app/Contents/MacOS/firefox'
if os.path.exists(binary) is False:
    raise ValueError("The binary path to Tor firefox does not exist.")
firefox_binary = FirefoxBinary(binary)


browser = None
def get_browser(binary=None):
    global browser  
    # only one instance of a browser opens, remove global for multiple instances
    if not browser: 
        browser = webdriver.Firefox(firefox_binary=binary)
    return browser

if __name__ == "__main__":
    browser = get_browser(binary=firefox_binary)
    urls = (
        ('tor browser check', 'https://check.torproject.org/'),
        ('ip checker', 'http://icanhazip.com')
    )
    for url_name, url in urls:
        print "getting", url_name, "at", url
        browser.get(url)

On an Ubuntu system I was able to run the Tor browser via selenium. This machine has tor running at port 9051 and privoxy http proxy that uses tor at port 8118. In order for the Tor browser to pass the tor check page I had to set the http proxy to privoxy.

from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
from selenium.webdriver.common.proxy import Proxy, ProxyType
from selenium import webdriver
browser = None

proxy_address = "127.0.0.1:8118"
proxy = Proxy({
    'proxyType': ProxyType.MANUAL,
    'httpProxy': proxy_address,
})

tor = '/usr/bin/tor-browser/Browser/firefox'
firefox_binary = FirefoxBinary(tor)

urls = (
    ('tor_browser_check', 'https://check.torproject.org/'),
    ('icanhazip', 'http://icanhazip.com'),
)
keys, _ = zip(*urls)
urls_map = dict(urls)

def get_browser(binary=None, proxy=None):
    global browser
    if not browser:
        browser = webdriver.Firefox(firefox_binary=binary, proxy=proxy)
    return browser

if __name__ == "__main__":
    browser = get_browser(binary=firefox_binary, proxy=proxy)
    for resource in keys:
        browser.get(urls_map.get(resource))
dmmfll
  • 2,666
  • 2
  • 35
  • 41
  • If you get ❝The proxy server is refusing connections❞ error then it is likely that you have not launched the TorBrowser app from the finder to get the SOCKS host running on port 9150. – dmmfll Apr 27 '15 at 20:54
  • Or you do not have tor and privoxy running on the local machine. – dmmfll Apr 27 '15 at 21:21
  • So you need to install tor and privoxy by hand, and then the script works? – serv-inc Sep 14 '15 at 15:40
  • 1
    Yes. Tor daemon running. Privoxy running. Setting in circa line 1314 of /etc/privoxy/config as such `forward-socks5t / 127.0.0.1:9050 .` assuming that interface and port on tor daemon. – dmmfll Sep 14 '15 at 15:52
  • 1
    Caveat: Know that this is in no way anonymously secure by tor-project standards. I just use it to change up the ip number. Coincidentally, at the moment you typed the comment I was just wondering why I was not getting a yellow light on `https://check.torproject.org/` and it was because I forgot to uncomment the line in privoxy config that I mentioned above. – dmmfll Sep 14 '15 at 16:06
  • @Dmfll after opening the Tor I get options: "I would like to make the direct connection to the Tor." and "This internet connection is censored or proxied". Any idea how get past that programmatically? I don't get the prompt when I open Tor manually. OS El Capitan. – RyGuy Aug 06 '16 at 05:43
  • 2
    On Mac, not working for me: `selenium.common.exceptions.WebDriverException: Message: 'geckodriver' executable needs to be in PATH` I am pointing firefox_binary to the bundle in Tor Browser.app, which is obvisusly not in my scripting folder. Also using venv if it can help. Anyone was able to launch it on Mac ? – user305883 Oct 17 '18 at 15:14
  • 1
    @user305883 I was having the same problem. Running `brew install geckodriver` solved it for me. – user760900 Jun 28 '20 at 21:15
  • It's not working if I have Tor preopened. I have to have it closed then click `connect` on program startup. Is there anyway to programmatically get a new identity? – user760900 Jun 28 '20 at 21:26
  • @user760900 don't quite remember about if/what I worked out. But want to avoid using brew. – user305883 Jun 29 '20 at 07:52
  • As of 2022 this reply is outdated – Life after Guest Mar 12 '22 at 09:27
9

//just check your tor browser's port number and change that accordingly in the //code

from selenium import webdriver
profile=webdriver.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', 9150)
browser=webdriver.Firefox(profile)
browser.get("http://yahoo.com")
browser.save_screenshot("screenshot.png")
browser.close()
Chirag Shetty
  • 91
  • 1
  • 1
  • I understand this post is 5 years old but I would like to point out that the code above opens up yahoo.com page in Mozilla Firefox not Tor Browser. How do we open the page in Tor? Thank you – Daniel Oct 23 '20 at 14:26
9

To open browser with Selenium driven GeckoDriver you need to:

  • Download and install the TOR Browser

  • Download the latest GeckoDriver v0.26.0 and place it in your system.

  • Install the recent Mozilla Firefox v77.0.1 browser.

  • You can use the following code block to open the TOR enabled browser:

    from selenium import webdriver
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
    import os
    
    torexe = os.popen(r'C:\Users\username\Desktop\Tor Browser\Browser\TorBrowser\Tor\tor.exe')
    profile = FirefoxProfile(r'C:\Users\username\Desktop\Tor Browser\Browser\TorBrowser\Data\Browser\profile.default')
    profile.set_preference('network.proxy.type', 1)
    profile.set_preference('network.proxy.socks', '127.0.0.1')
    profile.set_preference('network.proxy.socks_port', 9050)
    profile.set_preference("network.proxy.socks_remote_dns", False)
    profile.update_preferences()
    firefox_options = webdriver.FirefoxOptions()
    firefox_options.binary_location = r'C:\Program Files\Mozilla Firefox\firefox.exe'
    driver = webdriver.Firefox(firefox_profile= profile, options = firefox_options, executable_path=r'C:\WebDrivers\geckodriver.exe')
    driver.get("http://check.torproject.org")
    
  • Browser Snapshot:

torFirefox_torproject


Alternative using Firefox Nightly

As an alternative you can also download, install and use the recent Firefox Nightly v79.0a1 browser.

  • Code Block:

    from selenium import webdriver
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
    import os
    
    torexe = os.popen(r'C:\Users\username\Desktop\Tor Browser\Browser\TorBrowser\Tor\tor.exe')
    profile = FirefoxProfile(r'C:\Users\username\Desktop\Tor Browser\Browser\TorBrowser\Data\Browser\profile.default')
    profile.set_preference('network.proxy.type', 1)
    profile.set_preference('network.proxy.socks', '127.0.0.1')
    profile.set_preference('network.proxy.socks_port', 9050)
    profile.set_preference("network.proxy.socks_remote_dns", False)
    profile.update_preferences()
    firefox_options = webdriver.FirefoxOptions()
    firefox_options.binary_location = r'C:\Program Files\Firefox Nightly\firefox.exe'
    driver = webdriver.Firefox(firefox_profile= profile, options = firefox_options, executable_path=r'C:\WebDrivers\geckodriver.exe')
    driver.get("http://check.torproject.org")
    
  • Browser Snapshot:

torNightly_torproject


Alternative using Chrome

As an alternative you can also download, install and use the recent Chrome v84 browser.

  • Code Block:

    from selenium import webdriver
    import os
    
    torexe = os.popen(r'C:\Users\username\Desktop\Tor Browser\Browser\TorBrowser\Tor\tor.exe')
    PROXY = "socks5://localhost:9050" # IP:PORT or HOST:PORT
    options = webdriver.ChromeOptions()
    options.add_argument('--proxy-server=%s' % PROXY)
    driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
    driver.get("http://check.torproject.org")
    
  • Browser Snapshot:

torChrome_torproject


References

You can find a couple of relevant detailed discussions in:

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • It opens Tor Browser but when attempts to open a webpage I get the blank page with "The proxy server is refusing connection". I changed the port number and the proxy socks and still same message. Can you help here? Thanks – Daniel Oct 23 '20 at 14:57
  • I got it to work. The culprit was profile.set_preference('network.proxy.socks_port', 9050) Even if I change the port it doesn't, but removing the line completely fix the problem. – Daniel Oct 23 '20 at 15:08
  • @Daniel if you removed that, that implies you are not using tor? – Phani Rithvij Nov 01 '21 at 13:03
  • I got `selenium.common.exceptions.WebDriverException` with firefox and firefox-nightly on windows but with geckodriver it worked. – Phani Rithvij Nov 01 '21 at 13:04
1
from selenium import webdriver
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary

#path to TOR binary
binary = FirefoxBinary(r'...\Tor Browser\Browser\firefox.exe')
#path to TOR profile
profile = FirefoxProfile(r'...\Tor Browser\Browser\TorBrowser\Data\Browser\profile.default')

driver = webdriver.Firefox(firefox_profile= profile, firefox_binary= binary)
driver.get("http://icanhazip.com")
driver.save_screenshot("screenshot.png")
driver.quit()

Using Python 3.5.1 on Windows 10

Will D.
  • 19
  • 4
1

A lot of answers are towards the right direction but this is exactly what worked for me:

On Ubuntu:

You need to install Tor using apt command or other method, but not the binary version.

Installation guide:

https://linuxconfig.org/how-to-install-tor-browser-in-ubuntu-18-04-bionic-beaver-linux

Inside the sample.py you might need to:

  • set profile of the Firefox to torrc which is located most of the times in /etc/tor/.
  • set the binary to the Firefox binary of Tor, since Tor is just a series of configurations built atop of Firefox.

You also need the geckodriver to automate firefox with selenium:

Pay attension to the:

  • "network.proxy.socks_port" = 9150
  • Inside torrc ControlPort 9050, CookieAuthentication 1
  • Open TorBrowser
  • sudo lsof -i -P -n | grep LISTEN the LISTEN port of the tor network must be the same in the script
  • Run the python script, while TorBrowser is open

Thanks user2426679 https://stackoverflow.com/a/21836296/3816638 for the settings.

from selenium import webdriver
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
from selenium.webdriver.common.proxy import Proxy, ProxyType
from selenium.webdriver.firefox.options import Options
import subprocess
import os

profileTor = '/etc/tor/' #  torrc
binary = os.path.expanduser("~/.local/share/torbrowser/tbb/x86_64/tor-browser_en-US/Browser/firefox")

firefox_binary = FirefoxBinary(binary)
firefox_profile = FirefoxProfile(profileTor)


#set some privacy settings
firefox_profile.set_preference( "places.history.enabled", False )
firefox_profile.set_preference( "privacy.clearOnShutdown.offlineApps", True )
firefox_profile.set_preference( "privacy.clearOnShutdown.passwords", True )
firefox_profile.set_preference( "privacy.clearOnShutdown.siteSettings", True )   
firefox_profile.set_preference( "privacy.sanitize.sanitizeOnShutdown", True )
firefox_profile.set_preference( "signon.rememberSignons", False )
firefox_profile.set_preference( "network.cookie.lifetimePolicy", 2 )
firefox_profile.set_preference( "network.dns.disablePrefetch", True )
firefox_profile.set_preference( "network.http.sendRefererHeader", 0 )

#set socks proxy
firefox_profile.set_preference( "network.proxy.type", 1 )
firefox_profile.set_preference( "network.proxy.socks_version", 5 )
firefox_profile.set_preference( "network.proxy.socks", '127.0.0.1' )
firefox_profile.set_preference( "network.proxy.socks_port", 9150 )
firefox_profile.set_preference( "network.proxy.socks_remote_dns", True )

#if you're really hardcore about your security
#js can be used to reveal your true i.p.
firefox_profile.set_preference( "javascript.enabled", False )

#get a huge speed increase by not downloading images
firefox_profile.set_preference( "permissions.default.image", 2 )

options = Options()
options.set_headless(headless=False)

driver = webdriver.Firefox(firefox_profile=firefox_profile,firefox_options=options)

print(driver)

driver.get("https://check.torproject.org/")
driver.save_screenshot("screenshot.png")
0

Using ruby,

profile = Selenium::WebDriver::Firefox::Profile.new
profile.proxy = Selenium::WebDriver::Proxy.new :socks => '127.0.0.1:9050' #port where TOR runs
browser = Watir::Browser.new :firefox, :profile => profile

To confirm that you are using Tor, use https://check.torproject.org/

rdsoze
  • 1,768
  • 1
  • 15
  • 25
0

I looked into this, and unless I'm mistaken, on face value it's not possible.

The reason this cannot be done is because:

  • Tor Browser is based on the Firefox code.
  • Tor Browser has specific patches to the Firefox code to prevent external applications communicating with the Tor Browser (including blocking the Components.Interfaces library).
  • The Selenium Firefox WebDriver communicates with the browser through Javascript libraries that are, as aforementioned, blocked by Tor Browser.

This is presumably so no-one outside of the Tor Browser either on your box or over the internet knows about your browsing.

Your alternatives are:

  • Use a Tor proxy through Firefox instead of the Tor Browser (see the link in the comments of the question).
  • Rebuild the Firefox source code with the Tor Browser patches excluding those that prevent external communication with Tor Browser.

I suggest the former.

Willem van Ketwich
  • 5,666
  • 7
  • 49
  • 57
  • 1
    If you really want to use the TBB it can be done by (1) first starting the bundle. (2) After you see that Aurora has loaded you can (3) start selenium using the FF profile and executable found within the TBB. This will attach to the current Vidalia, and you can (4) close the original Aurora window that was opened. – sam-6174 Feb 21 '14 at 21:14
0

As a newer alternative to Selenium, which only controls Firefox, have a look at Marionette. To use with the Tor Browser, enable marionette at startup via

Browser/firefox -marionette

(inside the bundle). Then, you can connect via

from marionette import Marionette
client = Marionette('localhost', port=2828);
client.start_session()

and load a new page for example via

url='http://mozilla.org'
client.navigate(url);

For more examples, there is a tutorial.


Older answer

The Tor project has a selenium test for its browser. It works like:

from selenium import webdriver
ffbinary = webdriver.firefox.firefox_binary.FirefoxBinary(firefox_path=os.environ['TBB_BIN'])
ffprofile = webdriver.firefox.firefox_profile.FirefoxProfile(profile_directory=os.environ['TBB_PROFILE'])
self.driver = webdriver.Firefox(firefox_binary=ffbinary, firefox_profile=ffprofile)
self.driver.implicitly_wait(30)
self.base_url = "about:tor"
self.verificationErrors = []
self.accept_next_alert = True
self.driver.get("http://check.torproject.org/")
self.assertEqual("Congratulations. This browser is configured to use Tor.", driver.find_element_by_css_selector("h1.on").text)

As you see, this uses the environment variables TBB_BIN and TBB_PROFILE for the browser bundle and profile. You might be able to hardcode these in your code.

Community
  • 1
  • 1
serv-inc
  • 35,772
  • 9
  • 166
  • 188
  • what should be the value of TBB_BIN and TBB_PROFILE if I dont have them configure? – Shoham Aug 06 '16 at 20:25
  • @Shoham: marionette is really really easy to use, are you sure you want to try selenium? (If so, it depends on your OS, and if you installed by direct download or package manager. For Linux, it should be sth like `tor-browser_en-US/Browser` for TBB_BIN and `TBB_BIN + TorBrowser/Data/Browser/profile.default/` for TBB_PROFILE`) – serv-inc Aug 08 '16 at 16:11
0
System.setProperty("webdriver.firefox.marionette", "D:\\Lib\\geckodriver.exe");
        String torPath = "C:\\Users\\HP\\Desktop\\Tor Browser\\Browser\\firefox.exe";
        String profilePath = "C:\\Users\\HP\\Desktop\\Tor Browser\\Browser\\TorBrowser\\Data\\Browser\\profile.default";

        File torProfileDir = new File(profilePath);
        FirefoxBinary binary = new FirefoxBinary(new File(torPath));
        FirefoxProfile torProfile = new FirefoxProfile(torProfileDir);

        FirefoxOptions options = new FirefoxOptions();
        options.setBinary(binary);
        options.setProfile(torProfile);
        options.setCapability(FirefoxOptions.FIREFOX_OPTIONS,options);
        WebDriver driver = new FirefoxDriver(options);
Anuj Bansal
  • 117
  • 5
0

Referring to the answer @undetected Selenium . If you add to (or have in) PATH in windows : r'C:\Program Files\Mozilla Firefox\firefox.exe' and r'C:\WebDrivers\geckodriver.exe' then you can use a shortened block of code. Below I present a block of code that works for me:

import os

from selenium.webdriver import Firefox
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.webdriver.firefox.options import Options

# Variable with the URL of the website.
my_url = "http://check.torproject.org"

# Preparing of the Tor browser for the work.
torexe = os.popen(\
    r"C:\Users\olive\OneDrive\Pulpit\Tor Browser\Browser\firefox.exe")
profile = FirefoxProfile(\
    r"C:\Users\olive\OneDrive\Pulpit\Tor Browser\Browser\TorBrowser\Data"+\
    "\Browser\profile.default")
profile.set_preference("network.proxy.type", 1)
profile.set_preference("network.proxy.socks", "127.0.0.1")
profile.set_preference("network.proxy.socks_port", 9150)
profile.set_preference("network.proxy.socks_remote_dns", False)
profile.update_preferences()
firefox_options = Options()
driver = Firefox(firefox_profile= profile, options = firefox_options)
driver.get(my_url)
Olgierd Wiśniewski
  • 433
  • 2
  • 8
  • 14
  • "firefox_profile has been deprecated, please use an Options object" - this is what i get in the shell when i use this code. Unfortunately, I don't have time to develop the new code. I am using python 3.10.2. Maybe someone will take up this challenge. – Olgierd Wiśniewski Apr 07 '22 at 11:38
0

It is no longer necessary to download the webdriver manually, you can use it this way:

pip install selenium
pip install webdriver-manager

import time
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

# Chrome e Proxy Tor
servico = Service(ChromeDriverManager().install())
proxy = "socks5://127.0.0.1:9150"  # Tor
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument(f"--proxy-server={proxy}")
navegador = webdriver.Chrome(service=servico, options=chrome_options)

check_tor = 'https://check.torproject.org/'

navegador.get(check_tor)
time.sleep(10)

*** Obviously Tor Browser needs to be open.**

https://i.stack.imgur.com/krKMO.png

Dreker
  • 3
  • 2