无法使用HtmlUnit

时间:2016-07-21 10:19:51

标签: java htmlunit

我正在尝试下载recaptcha的所有图片,但不知怎的,我无法点击reC​​aptcha iframe的复选框。 单击它时,HtmlUnit会抛出WrappedException。我不确定为什么会发生这种情况 我怎么想点击链接并下载图片?我猜这是GWT的问题。我可以点击任何其他正常按钮。

任何帮助都将受到高度赞赏

主要网站是:https://www.google.com/recaptcha/api2/demo

到目前为止我已经完成了。

private static final Logger LOG = LoggerFactory.getLogger(Main.class);

    public static void main(String[] args) throws IOException {

        try (WebClient webClient = new WebClient(BrowserVersion.FIREFOX_38)) {
            webClient.getCache().clear();
            final WebClientOptions webClientOptions = webClient.getOptions();
            webClientOptions.setTimeout(40000);
            webClientOptions.setRedirectEnabled(false);
            // webClientOptions.setUseInsecureSSL(true);
            webClient.setAlertHandler(new AlertHandler() {
                public void handleAlert(Page page, String string) {
                    System.out.printf("alert: %s%n", string);
                    LOG.info("javascript alert: {}", string);
                }
            });
            webClientOptions.setJavaScriptEnabled(true);
            webClient.setCssErrorHandler(new SilentCssErrorHandler());
          //  webClient.setAjaxController(new NicelyResynchronizingAjaxController());
            webClientOptions.setThrowExceptionOnScriptError(false);
            webClientOptions.setThrowExceptionOnFailingStatusCode(false);


            HtmlPage reCaptchaFrame;

            final HtmlPage page = webClient.getPage("https://www.google.com/recaptcha/api2/demo");
            webClient.getJavaScriptEngine().pumpEventLoop(1000);
            webClient.waitForBackgroundJavaScript(200);

            int waitForBackgroundJavaScript = webClient.waitForBackgroundJavaScript(200);
            int loopCount = 0;
            while (waitForBackgroundJavaScript > 0 && loopCount < 2) {
                ++loopCount;
                waitForBackgroundJavaScript = webClient.waitForBackgroundJavaScript(200);
                if (waitForBackgroundJavaScript == 0) {
                    if (LOG.isTraceEnabled())
                        LOG.trace("HtmlUnit exits background javascript at loop counter " + loopCount);
                    break;
                 }
            }

            JavaScriptEngine engine = webClient.getJavaScriptEngine();
            engine.holdPosponedActions();
            final List<FrameWindow> frames = page.getFrames();

            reCaptchaFrame = (HtmlPage) frames.get(0).getEnclosedPage();
            // initiating to enter the reCaptcha

            final HtmlSpan reCaptchaAnchor =  reCaptchaFrame.getFirstByXPath(".//span[@id='recaptcha-anchor']");

            if (reCaptchaAnchor == null) {
                 throw new NullPointerException("Captcha not found");
            }

            try {
                 HtmlPage page1 = reCaptchaAnchor.click(); // here I get the exception

            } catch (WrappedException e) {
                 LOG.info("Found some stupid exception {}", e.details());
            }
        } catch (Exception e) {
            LOG.info("Found exception {}", e.getMessage());
        } 
     }

堆栈跟踪:

net.sourceforge.htmlunit.corejs.javascript.WrappedException: Wrapped java.lang.NullPointerException
at     net.sourceforge.htmlunit.corejs.javascript.Context.throwAsScriptRuntimeEx(Con text.java:2053)
at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.doProcessPostponedActions(JavaScriptEngine.java:1007)
at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.processPostponedActions(JavaScriptEngine.java:1072)
at com.gargoylesoftware.htmlunit.html.DomElement.click(DomElement.java:789)
at com.gargoylesoftware.htmlunit.html.DomElement.click(DomElement.java:732)
at com.gargoylesoftware.htmlunit.html.DomElement.click(DomElement.java:679)
at recaptchatest.Main.main(Main.java:77)
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:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.NullPointerException
at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.hasTopCall(ScriptRuntime.java:3263)
at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:102)
at com.gargoylesoftware.htmlunit.javascript.host.Promise$1.execute(Promise.java:136)
at      com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.doProcessPostponedActions(JavaScriptEngine.java:1002)
... 10 more

2 个答案:

答案 0 :(得分:1)

将HTMLUnit升级到2.22并将htmlunit-core-js库升级到2.22后,所有内容都按预期工作。

答案 1 :(得分:0)

我建议你检查元素的实际XPATH是什么。

这个方框有一个类=&#39; recaptcha-checkbox-checkmark&#39;

您可以将XPath用于:

 reCaptchaFrame.getFirstByXPath("//div[@class='recaptcha-checkbox-checkmark']");

如果失败,请尝试使用除XPATH之外的其他选择方法,可能是CSS,这是queryselector方法。

这是:

reCaptchaFrame.querySelector("recaptcha-checkbox-checkmark");   

要在没有出现错误的情况下进行分配,请使用HtmlElement强制转换网络上的所有元素。

HtmlElement a = reCaptchaFrame.querySelector("recaptcha-checkbox-checkmark");
a.click();