在(任何)Java程序中渲染JavaScript和HTML(访问渲染的DOM树)?

2022-09-03 02:23:16

什么是最好的Java库来“完全下载任何网页并呈现内置的JavaScript,然后访问呈现的网页(即DOM树!以编程方式获取 DOM 树作为“HTML 源代码”?

(类似于firebug最终所做的,它呈现页面,我可以访问完全呈现的DOM树,就像页面在浏览器中一样!相比之下,如果我点击“显示源代码”,我只得到JavaScript源代码。这不是我想要的。我需要有权访问呈现的页面...)

(对于渲染,我的意思是只渲染DOM树而不是可视化渲染...)

这不一定是一个单一的库,有几个库可以一起完成这个任务是可以的(一个将下载,一个渲染...),但由于JavaScript的动态特性,JavaScript库很可能还必须具有某种下载器才能完全呈现任何异步JS...

背景:
在“美好的过去”,HttpClient(Apache库)是构建自己非常简单的爬虫所需的一切。(很多像 Nutch 或 Heretrix 这样的 cralwers 仍然围绕这个核心 princible 构建,主要关注标准 HTML 解析,所以我无法从中学习)我的问题是,我需要抓取一些严重依赖JavaScript的网站,并且我无法使用HttpClient进行解析,因为我之前需要执行JavaScripts。


答案 1

您可以使用 JavaFX 2 。下载 JavaFX SDK (如果您安装了 JDK7u2 或更高版本,您可能已经拥有它)并尝试下面的代码。WebEngine

它将使用经过处理的javascript打印html。您可以取消注释中间的线条以查看渲染。

public class WebLauncher extends Application {

    @Override
    public void start(Stage stage) {
        final WebView webView = new WebView();
        final WebEngine webEngine = webView.getEngine();
        webEngine.load("http://stackoverflow.com");
        //stage.setScene(new Scene(webView));
        //stage.show();

        webEngine.getLoadWorker().workDoneProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                if (newValue.intValue() == 100 /*percents*/) {
                    try {
                        org.w3c.dom.Document doc = webEngine.getDocument();
                        new XMLSerializer(System.out, new OutputFormat(doc, "UTF-8", true)).serialize(doc);
                    } catch (IOException ex) { 
                        ex.printStackTrace();
                    }
                }
            }
        });

    }

    public static void main(String[] args) {
        launch();
    }

}

答案 2

这有点开箱即用,但是如果您计划在完全控制环境的服务器中运行代码,则它可能会起作用...

在你的机器上安装Firefox(或XulRunner,如果你想保持轻量级的话)。

使用Firefox插件系统,编写一个小插件,加载给定的URL,等待几秒钟,然后将页面的DOM复制到字符串中。

从这个插件中,使用Java LiveConnect API(参见 http://jdk6.java.net/plugin2/liveconnect/https://developer.mozilla.org/en/LiveConnect)将该字符串推送到一些嵌入式Java代码中的公共静态函数,这些函数可以自己执行所需的处理,也可以将其归为一些更复杂的代码。

好处:您使用的是大多数应用程序开发人员都面向的浏览器,因此观察到的行为应该具有可比性。您还可以沿正常升级路径升级浏览器,这样您的库就不会随着 HTML 标准的变化而过时。

弊:您需要具有在服务器上启动非无外设应用程序的权限。您还需要担心进程间通信的复杂性。

我以前使用过插件API来调用Java,这是可以实现的。如果你想要一些示例代码,你应该看看XQuery插件 - 它从DOM加载XQuery代码,将其传递到Java Saxon库进行处理,然后将结果推送回浏览器。这里有一些关于它的细节:

https://developer.mozilla.org/en/XQuery