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

我知道此类问题必须在此之前提出,但通过搜索我没有找到解决方案:

我的问题是:什么是最好的Java库“完全下载任何wepage并呈现内置的JavaScript,然后以编程方式访问呈现的网页(即DOM-Tree!),并将DOM树作为”HTML -资源”。

(类似于firebug最终做的事情,它呈现页面,我可以访问完全呈现的DOM树,因为页面在浏览器中看起来像!相反,如果我点击“show source”我只获得JavaScript源代码这不是我想要的。我需要访问渲染的页面…)

(使用渲染我的意思是只渲染DOM树而不是视觉渲染……)

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

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

非常感谢你!! 蒂姆

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

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

使用Firefox插件系统,编写一个小插件,它接受给定URL的加载,等待几秒钟,将页面的DOM复制到String中。

从这个插件中,使用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

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

它会打印带有处理过的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() { @Override public void changed(ObservableValue 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(); } } 

Selenium库通常用于测试,但可以让您远程控制大多数标准浏览器(IE,Firefox等)以及无头浏览器免费模式(使用HtmlUnit)。 因为它旨在通过页面抓取进行UIvalidation,所以它可能很适合您的目的。

根据我的经验,它有时会遇到速度很慢的JavaScript,但仔细使用“等待”命令就可以获得非常可靠的结果。

它还有一个好处,你可以实际驱动页面,而不仅仅是刮掉它。 这意味着如果您在获得所需数据之前在页面上执行某些操作(单击搜索按钮,单击“下一步”,然后单击“刮”),则可以将其编码到该过程中。

我不知道你是否能够从Selenium以可导航的forms获得完整的DOM,但它确实为页面的各个部分提供了XPath检索,这是你通常需要的一个抓取应用程序。

您可以使用带有或不带Grails的Java,Groovy。 然后使用Webdriver,Selenium,Spock和Geb这些用于测试目的,但这些库对您的情况很有用。 您可以实现一个不会打开新窗口但只是这些浏览器的运行时的Crawler。

  • Selenium: http : //code.google.com/p/selenium/
  • Webdriver: http ://seleniumhq.org/projects/webdriver/
  • Spock: http : //code.google.com/p/spock/
  • Geb: http : //www.gebish.org/manual/current/testing.html

MozSwing可以帮助http://confluence.concord.org/display/MZSW/Home 。

你可以尝试JExplorer。 有关更多信息,请访问http://www.teamdev.com/downloads/jexplorer/docs/JExplorer-PGuide.html

您也可以尝试Cobra,请参阅http://lobobrowser.org/cobra.jsp

我没有尝试过这个项目,但我已经看到了几个包含javascript dom操作的node.js实现。

https://github.com/tmpvar/jsdom