Search code examples
javafirefoxselenium-webdrivertortor-browser-bundle

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\\My User\\Desktop\\Tor Browser\\Start Tor Browser.exe";
String profilePath = "C:\\Users\\My User\\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.


Solution

  • 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;
      }