我正在尝试使用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
如何防止此错误或至少捕获该错误并进行有效处理?
最佳答案
发生UnreachableBrowserException的原因可能多种多样-最明显的是,浏览器已关闭(无论是在代码中还是在GUI中),然后代码都尝试访问它。通常,就像您的情况一样,它们是由套接字错误引起的。同样,这可能意味着很多事情-您的程序试图打开太多的套接字,无法连接到远程网站,等等。
我建议在这种情况下要等待一小段时间,然后重试以查看是否仍然抛出异常。有时这些情况会自行解决,您的程序可以恢复。
这是一些代码。只要抛出UnreachableBrowserException并且重试次数低于您设置的限制,它就会一直重试。如果达到重试限制并且仍然引发异常,它将关闭浏览器并重新启动,将重试计数重置为0。还有一个重新启动计数器,以确保如果由于某种原因重新启动浏览器不会帮助,您不会无休止地循环运行代码->异常->等待->重试->达到重试限制,重新启动浏览器->运行代码->异常。在这里,超过重启限制(或成功访问浏览器)将脱离循环。
如果您需要更多帮助,请告诉我。希望这会有所帮助!
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);