htmlunit无法从undefined中读取属性"push"

Mav*_*283 7 java web-crawler htmlunit

我正在尝试使用htmlunit抓取网站.每当我运行它,它只输出以下错误:

Caused by: net.sourceforge.htmlunit.corejs.javascript.EcmaError: TypeError: Cannot read property "push" from undefined (https://www.kinoheld.de/dist/prod/0.4.7/widget.js#1)
Run Code Online (Sandbox Code Playgroud)

现在我对JS不太了解,但我读到的push是某种数组操作.这对我来说似乎是标准的,我不知道为什么htmlunit不支持它.

这是我到目前为止使用的代码:

public static void main(String[] args) throws IOException {
    WebClient web = new WebClient(BrowserVersion.FIREFOX_45);
    web.getOptions().setUseInsecureSSL(true);
    String url = "https://www.kinoheld.de/kino-muenchen/royal-filmpalast/vorstellung/280823/?mode=widget&showID=280828#panel-seats";
    web.getOptions().setThrowExceptionOnFailingStatusCode(false);
    web.waitForBackgroundJavaScript(9000);
    HtmlPage response = web.getPage(url);

    System.out.println(response.getTitleText());
}
Run Code Online (Sandbox Code Playgroud)

我错过了什么?有没有办法绕过这个或解决这个问题的方法?提前致谢!

Gen*_*der 6

尝试添加

web.getOptions().setThrowExceptionOnScriptError(false);
Run Code Online (Sandbox Code Playgroud)

在你尝试获取页面之前.这迫使htmlunit忽略错误.但是,如果例如抛出错误的javascript对于获取正在废弃的数据(希望不是这样)很重要,那么这可能不会100%有效.如果这不起作用,请尝试将Selenium与ChromeDriver或GhostDriver一起使用.

资源

  • 我真的希望我可以将50分分开,而@Jack的回答确实解决了这个问题,你的建议可能对我来说更有帮助... (2认同)

Jac*_*ack 5

我之前遇到过类似的问题.这是HTML单元被设计为测试工具框架而不是网络抓取框架的问题.您是否在运行最新版本的HTML单元?

我能够通过添加setThrowExceptionOnScriptError(false)(如Coffee Converter的答案中提到的)行以及java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(java.util.logging.Level.OFF); 在方法顶部添加 禁用日志转储来运行代码.这产生了以下输出:

Royal Filmpalast München München | kinoheld.de
Run Code Online (Sandbox Code Playgroud)

完整代码如下:

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

    java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(java.util.logging.Level.OFF);

    WebClient webClient = new WebClient(BrowserVersion.FIREFOX_45);
    String url = "https://www.kinoheld.de/kino-muenchen/royal-filmpalast/vorstellung/280823/?mode=widget&showID=280828#panel-seats";

    webClient.getOptions().setUseInsecureSSL(true);
    webClient.getOptions().setThrowExceptionOnScriptError(false);
    webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
    webClient.waitForBackgroundJavaScript(9000);
    HtmlPage response = webClient.getPage(url);

    System.out.println(response.getTitleText());
}
Run Code Online (Sandbox Code Playgroud)

这是在具有HTML单元2.2.1的RedHat命令行上运行的.希望这可以帮助.