Selenium偶尔会出现UnreachableBrowserException

我试图通过在Java中使用Selenium来访问多个网站。 偶尔,我得到一个UnreachableBrowserException 。 我已经读过很多关于这个错误的线索,但似乎有很多不同的错误原因。 当我尝试访问新页面时,我得到的错误大约是1%的时间,我发现事件之间没有任何相似之处。 我目前正在使用Firefox,但我也尝试过Internet Explorer并遇到过类似的错误。 我一次只打开一个页面并尝试使用相同的窗口并在尝试访问另一个页面之前完全退出驱动程序,无论哪种方式仍然出现错误。 重要的是要注意我并不总是得到这个错误有时我的代码可以运行而不会发生这种情况。 这是错误消息:

 Jan 12, 2015 10:39:40 PM org.apache.http.impl.execchain.RetryExec execute INFO: I/O exception (java.net.SocketException) caught when processing request to {}- http://127.0.0.1:7055: Permission denied: connect Jan 12, 2015 10:39:40 PM org.apache.http.impl.execchain.RetryExec execute INFO: Retrying request to {}->http://127.0.0.1:7055 Jan 12, 2015 10:39:40 PM org.apache.http.impl.execchain.RetryExec execute INFO: I/O exception (java.net.SocketException) caught when processing request to {}->http://127.0.0.1:7055: Permission denied: connect Jan 12, 2015 10:39:40 PM org.apache.http.impl.execchain.RetryExec execute INFO: Retrying request to {}->http://127.0.0.1:7055 Jan 12, 2015 10:39:40 PM org.apache.http.impl.execchain.RetryExec execute INFO: I/O exception (java.net.SocketException) caught when processing request to {}->http://127.0.0.1:7055: Permission denied: connect Jan 12, 2015 10:39:40 PM org.apache.http.impl.execchain.RetryExec execute INFO: Retrying request to {}->http://127.0.0.1:7055 Jan 12, 2015 10:39:40 PM org.apache.http.impl.execchain.RetryExec execute INFO: I/O exception (java.net.SocketException) caught when processing request to {}->http://127.0.0.1:7055: Permission denied: connect Jan 12, 2015 10:39:40 PM org.apache.http.impl.execchain.RetryExec execute INFO: Retrying request to {}->http://127.0.0.1:7055 Jan 12, 2015 10:39:40 PM org.apache.http.impl.execchain.RetryExec execute INFO: I/O exception (java.net.SocketException) caught when processing request to {}->http://127.0.0.1:7055: Permission denied: connect Jan 12, 2015 10:39:40 PM org.apache.http.impl.execchain.RetryExec execute INFO: Retrying request to {}->http://127.0.0.1:7055 Jan 12, 2015 10:39:40 PM org.apache.http.impl.execchain.RetryExec execute INFO: I/O exception (java.net.SocketException) caught when processing request to {}->http://127.0.0.1:7055: Permission denied: connect Jan 12, 2015 10:39:40 PM org.apache.http.impl.execchain.RetryExec execute INFO: Retrying request to {}->http://127.0.0.1:7055 Exception in thread "main" org.openqa.selenium.remote.UnreachableBrowserException: Error communicating with the remote browser. It may have died. Build info: version: '2.44.0', revision: '76d78cf', time: '2014-10-23 20:03:00' System info: host: '****', ip: '**.*.*.*', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_60' Driver info: driver.version: RemoteWebDriver at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:593) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:614) at org.openqa.selenium.remote.RemoteWebDriver.quit(RemoteWebDriver.java:468) at scrape.Scraper.killInstance(Scraper.java:162) at scrape.Updater.main(Updater.java:93) Caused by: java.net.SocketException: Permission denied: connect at java.net.DualStackPlainSocketImpl.connect0(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) at java.net.AbstractPlainSocketImpl.connect(Unknown Source) at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.SocksSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:72) at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:123) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:318) at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:363) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57) at org.openqa.selenium.remote.HttpCommandExecutor.fallBackExecute(HttpCommandExecutor.java:215) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:184) at org.openqa.selenium.firefox.internal.NewProfileExtensionConnection.execute(NewProfileExtensionConnection.java:165) at org.openqa.selenium.firefox.FirefoxDriver$LazyCommandExecutor.execute(FirefoxDriver.java:362) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:572) ... 4 more 

如何防止此错误或至少捕获错误并有效地处理它?

UnreachableBrowserExceptions可能由于多种原因而发生 – 最明显的是浏览器在代码中或物理上在GUI中关闭,然后代码尝试访问它。 通常,就像你的情况一样,它们是由套接字错误引起的。 这可能意味着多件事 – 您的程序试图打开太多套接字,无法连接到远程网站,等等。

我建议在这种情况下做的是等待很短的时间,然后重试以查看是否仍然抛出exception。 有时这些情况会自行解决,您的程序可以恢复。

这是一些代码来做到这一点。 只要抛出UnreachableBrowserException并且重试次数低于您设置的某个限制,它就会一直重试。 如果它达到重试限制并且仍然抛出exception,它将关闭浏览器并重新启动它,将重试计数重置为0.还有一个重启计数器,以确保如果由于某种原因重新启动浏览器不帮助,你不要无休止地循环运行代码 – >exception – >等待 – >重试 – >命中重试限制,重启浏览器 – >运行代码 – >exception。 在这里,超过重启限制(或成功访问浏览器)将突破循环。

如果您需要更多帮助,请告诉我。希望这对您有所帮助!

 WebDriver driver = new FirefoxDriver(); //or whatever you're using boolean worked = false; int numredos = 0; final int REDO_LIMIT = 3; //or however many times you want to retry before giving up final int RESTART_LIMIT = 3; //or however many times you want to restart the browser b/f terminating int numrestarts = 0; boolean restart = false; do { try{ if(restart) { driver = new FirefoxDriver(); numrestarts++; } //RUN YOUR BROWSER CODE HERE worked = true; } //if the browser becomes unreachable (probably b/c of a socket issue), // write the error to the log and then sleep for 10 seconds //if we've already retried the set limit number of times, restart the browser and try again catch (UnreachableBrowserException ube) { worked = false; if(numredos >= REDO_LIMIT) { //if you've already restarted the browser too many times, it will set it to null //and return an error code. If not, it will set the restart flag so it will be restarted on the next iteration. //try quitting. If it can't do it, it's already dead; just set it to null //(set it to null either way, just in case) try { driver.quit(); } catch(Exception j) { errorwriter.println(j); } driver = null; if(numrestarts < RESTART_LIMIT) { //log that you're restarting the driver (not coded here), then set the restart flag to true. This will cause the browser to be restarted after falling out of the catch block numredos = 0; restart = true; } } else { //print details of the exception to the error file errorfile.println("\n\n\n"); //timestamp, and some exception details - you can decide which you want errorfile.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime())); errorfile.println(s.getClass()); errorfile.println(s.getMessage()); errorfile.println("Cause: " + s.getCause()); errorfile.flush(); //now sleep for some number of seconds - here 10 try { TimeUnit.SECONDS.sleep(10); } catch(InterruptedException e) { System.out.println("waiting after socket crash interrupted"); } numredos++; } } }while(!worked && numredos <= REDO_LIMIT && numrestarts <= RESTART_LIMIT);