Joel Christophel Joel Christophel - 1 year ago 451
Java Question

Using Selenium WebDriver with Tor

Because Tor Browser Bundle is just a patched version of Firefox, it seems that it should be possible to use a

FirefoxDriver
with Tor Browser. This is what I've tried so far:

String torPath = "C:\\Users\\Christophel Family\\Desktop\\Tor Browser\\Start Tor Browser.exe";
String profilePath = "C:\\Users\\Christophel Family\\Desktop\\Tor Browser\\Data\\Browser\\profile.default";
FirefoxProfile profile = new FirefoxProfile(new File(profilePath));
FirefoxBinary binary = new FirefoxBinary(new File(torPath));
FirefoxDriver driver = new FirefoxDriver(binary, profile);
driver.get("http://www.google.com");


This results in a blank Tor Browser page opening with a popup message: Your Firefox profile cannot be loaded. It may be missing or inaccessible.

I know that the profile is valid/compatible because I can successfully start the browser and profile with:

binary.startProfile(profile, profilePath, ""));


I don't know how to send commands to a browser opened in such a manner, however.

I've found similar questions, but I'm specifically looking for a Java solution, preferably tested on Windows.

I'm using a standalone Selenium library that can be downloaded here and the Tor Browser Bundle that can be downloaded here.

Answer Source

Because Tor Browser Bundle wasn't letting me use the WebDriver extension, I found a workaround in which I ran Tor from a regular Firefox browser. With this method, as long as the Tor Browser is open, you can use Tor with a regular Firefox browser.

  • Open Tor Browser:

    File torProfileDir = new File(
            "...\\Tor Browser\\Data\\Browser\\profile.default");
    FirefoxBinary binary = new FirefoxBinary(new File(
            "...\\Tor Browser\\Start Tor Browser.exe"));
    FirefoxProfile torProfile = new FirefoxProfile(torProfileDir);
    torProfile.setPreference("webdriver.load.strategy", "unstable");
    
    try {
        binary.startProfile(torProfile, torProfileDir, "");
    } catch (IOException e) {
        e.printStackTrace();
    }
    
  • Open Firefox with some configurations:

    FirefoxProfile profile = new FirefoxProfile();
    profile.setPreference("network.proxy.type", 1);
    profile.setPreference("network.proxy.socks", "127.0.0.1");
    profile.setPreference("network.proxy.socks_port", 9150);
    FirefoxDriver = new FirefoxDriver(profile);
    
  • Close browsers. Note that if you plan on doing a lot of closing and reopening (useful in obtaining a new IP address), I advise setting the profile preference toolkit.startup.max_resumed_crashes to a high value like 9999.

    private void killFirefox() {
        Runtime rt = Runtime.getRuntime();
    
        try {
            rt.exec("taskkill /F /IM firefox.exe");
            while (processIsRunning("firefox.exe")) {
                Thread.sleep(100);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private boolean processIsRunning(String process) {
        boolean processIsRunning = false;
        String line;
        try {
            Process proc = Runtime.getRuntime().exec("wmic.exe");
            BufferedReader input = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            OutputStreamWriter oStream = new OutputStreamWriter(proc.getOutputStream());
            oStream.write("process where name='" + process + "'");
            oStream.flush();
            oStream.close();
            while ((line = input.readLine()) != null) {
                if (line.toLowerCase().contains("caption")) {
                    processIsRunning = true;
                    break;
                }
            }
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return processIsRunning;
    }