Selenium HtmlUnitDriver 程序中捕获的 SocketException

Posted

技术标签:

【中文标题】Selenium HtmlUnitDriver 程序中捕获的 SocketException【英文标题】:SocketException caught in Selenium HtmlUnitDriver program 【发布时间】:2017-03-17 05:22:23 【问题描述】:

我编写了一个小脚本,它采用我们在我公司收到的 Epson 打印机的默认 IP 地址,并根据要求自动更改它们。这是使用 Selenium htmlUnitDriver 完成的。

脚本获取页面,插入新 IP,然后提交。因为我们第二次提交后IP就变了,页面不再是192.168.192.168,脚本也不想完成。

下面是脚本:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;

public class Main 
    public static void main(String[] args) 

        // Creating a new instance of the HTML unit driver.
        WebDriver driver = new HtmlUnitDriver();
        driver.get("http://192.168.192.168/ctcpip.htm");

        // Find and change the IP Address field.
        WebElement element = driver.findElement(By.name("IpAddress"));
        element.clear();
        element.sendKeys("192.168.192.169");
        element.submit();

        // Reset the printer. This changes it's IP as well, causing the initial driver page to no longer exist.
        WebElement reset = driver.findElement(By.name("Submit"));
        reset.submit();

        // The script never gets this far.
        driver.quit();

    

脚本在完成之前超时。单击reset 元素时,http://192.168.192.168/ctcpip.htm 的初始 URL 实际上不存在,因为我们已将其更改为 192.169.192.169。这是预期的行为,也是程序的重点。

控制台显示:

Nov 03, 2016 10:36:52 AM org.apache.http.impl.execchain.RetryExec execute
INFO: I/O exception (java.net.SocketException) caught when processing request to ->http://192.168.192.168:80: Operation timed out
Nov 03, 2016 10:36:52 AM org.apache.http.impl.execchain.RetryExec execute
INFO: Retrying request to ->http://192.168.192.168:80
Exception in thread "main" java.lang.RuntimeException: org.apache.http.conn.HttpHostConnectException: Connect to 192.168.192.168:80 [/192.168.192.168] failed: Operation timed out
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.doProcessPostponedActions(JavaScriptEngine.java:739)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.processPostponedActions(JavaScriptEngine.java:820)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.click(HtmlElement.java:1325)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.click(HtmlElement.java:1268)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.click(HtmlElement.java:1216)
    at org.openqa.selenium.htmlunit.HtmlUnitWebElement.submit(HtmlUnitWebElement.java:175)
    at Main.main(Main.java:19)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: org.apache.http.conn.HttpHostConnectException: Connect to 192.168.192.168:80 [/192.168.192.168] failed: Operation timed out
    at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:140)
    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 com.gargoylesoftware.htmlunit.HttpWebConnection.getResponse(HttpWebConnection.java:178)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnection(WebClient.java:1313)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponse(WebClient.java:1230)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:338)
    at com.gargoylesoftware.htmlunit.WaitingRefreshHandler.handleRefresh(WaitingRefreshHandler.java:92)
    at com.gargoylesoftware.htmlunit.html.HtmlPage.executeRefreshIfNeeded(HtmlPage.java:1446)
    at com.gargoylesoftware.htmlunit.html.HtmlPage.initialize(HtmlPage.java:306)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseInto(WebClient.java:475)
    at com.gargoylesoftware.htmlunit.WebClient.loadDownloadedResponses(WebClient.java:2074)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.doProcessPostponedActions(JavaScriptEngine.java:733)
    ... 11 more
Caused by: java.net.ConnectException: Operation timed out
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:72)
    at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:123)
    ... 29 more

Process finished with exit code 1

我如何告诉我的驱动程序实例更改页面非常酷,以便进程可以正常退出?

脚本需要到达driver.quit();行。

【问题讨论】:

脚本缺少同步。在这段代码之后使用同步方法 -> element.sendKeys("192.168.192.169"); element.submit(); 暂时尝试使用thread.sleep,如果你得到同样的异常。在这里只是在黑暗中拍摄。 @Sai 很遗憾没用。试图看看我是否可以通过隐式/显式等待来做某事。 @jagdpanzer 更改 IPAddress 后会发生什么?页面是否刷新?它会重新打开窗口吗? @Buaban 页面尝试刷新,由于IPAddress更改总是会失败(看到IPAddress是我们用来连接的)。 【参考方案1】:

你有没有试过打电话

driver.quit();

之前

reset.submit();

?您不再使用驱动程序来检索任何元素,因此您可以在提交页面之前退出。

希望对你有帮助。

【讨论】:

为什么在点击重置按钮之前退出浏览器可以解决问题?如果您知道 IP 可以更改并导致 SocketTimeOutException,则它更多的是异常处理(因为您已经知道可能会出现异常)问题,而不是在单击重置按钮之前退出浏览器。如果您在 reset.submit 之前调用 driver.quit,则永远不会调用重置按钮代码。这是您期望的行为吗?【参考方案2】:

如果 Selenium 中的 findelement 不能正常工作,每个人都使用 js :)。 这个怎么样?

 driver.executeScript("window.document.getElementsByName("Submit")[0].click()");

索引可能有误,需要调整

【讨论】:

使用 js.executeScript("window.document.getElementsByName('Submit')[0].click()"); 会导致超时错误 - 它找不到元素。 这会返回什么(仅在 Web 控制台中)? window.document.getElementsByName('Submit'‌​) 我的问题不在于点击。该点击通过,打印机成功重置为新 IP 地址,但脚本无法正常退出,这使我无法同时操作。 你能伪造/伪造 GET (?) 请求吗? :) 那会是另一个driver.get()吗?比如driver.get(http://192.168.192.169/)?【参考方案3】:

请尝试使用以下代码:

如果提供的主机或主机 IP 地址在网络中不可用,它将退出驱动程序。


import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;

public class Main 
    public static void main(String[] args) 

    // Creating a new instance of the HTML unit driver.
        WebDriver driver = new HtmlUnitDriver();
        try
            driver.get("http://192.168.192.168/ctcpip.htm");
            WebElement element = driver.findElement(By.name("IpAddress"));
            element.clear();
            element.sendKeys("192.168.192.169");
            element.submit();

        // Reset the printer. This changes it's IP as well, causing the   initial driver page to no longer exist.
            WebElement reset = driver.findElement(By.name("Submit"));
            reset.submit();
        
        catch(HttpHostConnectException e)
            System.out.println("Host Not Found : "+ e.getMessage())
        

        finally
        driver.quit();
        
    

【讨论】:

HttpHostConnectException 是未经检查的异常。 HttpHostConnectException 的捕获没有为我编译。 对于任何异常,如果您使用 try 和 catch 或 throws 处理(向编译器发出信号,我知道)在编译代码时不会给您任何问题。如果您要检查类路径中是否缺少任何库。在特定的 Http 客户端库中

以上是关于Selenium HtmlUnitDriver 程序中捕获的 SocketException的主要内容,如果未能解决你的问题,请参考以下文章

为啥 HtmlUnitDriver 不执行 JavaScript?

如何使用无头(gui-less)Selenium WebDriver下载文件

在 Java 中使用 Selenium 与 wep 页面交互时遇到问题

Selenium WebDriver的使用

Selenium 例程第一次工作,但后续运行失败

如何为搜索引擎优化 PhantomJS 以索引单页应用程序?