用JavaScript渲染的Java作为字符串,获取最终HTML。

12

我想从一个HTML页面中获取数据(进行抓取),但是其中包含了用Javascript编写的评论。在正常的Java URL获取中,我只能获取到未执行Javascript的HTML内容。我需要最终执行Javascript的页面。

例如:- http://www.glamsham.com/movies/reviews/rowdy-rathore-movie-review-cheers-for-rowdy-akki-051207.asp

该页面有Facebook插件评论,这些评论被当做Javascript获取。

类似于此的还有这个链接: http://www.imdb.com/title/tt0848228/reviews

我该怎么办?


1
你在一般情况下唯一真正的选择是将Web浏览器作为自己软件的组件来利用。让浏览器获取页面并模拟JavaScript所需的任何交互,然后检查DOM。 - Pointy
应该有一种方法来实现Facebook API,以便从该帖子中获取评论,同时与页面的其余内容一起获取。 - Fabrício Matté
3个回答

7

Use phantomjs: http://phantomjs.org

var page = require('webpage').create();
page.open("http://www.glamsham.com/movies/reviews/rowdy-rathore-movie-review-cheers-for-rowdy-akki-051207.asp")
setTimeout(function(){
    // Where you want to save it    
    page.render("screenshoot.png")  
    // You can access its content using jQuery
    var fbcomments = page.evaluate(function(){
        return $(".fb-comments iframe").contents().find(".postContainer") 
    }) 
},10000)

您需要在phantom中使用选项--web-security=no来允许跨域交互(例如Facebook iframe)。

要与phantomjs中的其他应用程序通信,您可以使用Web服务器或进行POST请求:https://github.com/ariya/phantomjs/blob/master/examples/post.js


@Ivan 我想用Java而不是JavaScript来完成这个任务 :P。爬取数据必须使用Java。 - KillerTheLord
4
不用土豆做这件事是一件好事;因为那会很难! - Ivan Castellanos
@IvanCastellanos 我同意这应该可以工作,但我在某些特定网站上无法获取呈现的HTML。例如,该网站将像'SITE_BACKGROUND'这样的元素呈现在另一个元素中,但phantom永远看不到它。请参见GIST https://gist.github.com/bizmate/db23887a7c5b066afafe2cc05acdd4ff。为什么会超时而不是获取呈现的html? - Bizmate

6
你可以使用HTML Unit,这是一个基于Java的“无界面浏览器”。由于它以网页浏览器的方式加载页面并返回最终渲染输出,因此您可以轻松获取任何页面的最终渲染输出。不过,您也可以禁用此行为。 更新: 你要求示例吗?你不需要额外做任何事情: 示例:
WebClient webClient = new WebClient();
HtmlPage myPage = ((HtmlPage) webClient.getPage(myUrl));

更新2: 您可以按以下方式获取iframe:

HtmlPage myFrame = (HtmlPage) myPage.getFrameByName(myIframeName).getEnclosedPage();

请阅读上面链接中的文档。使用HTMLUnit获取页面内容无所不能。

但是如果页面包含一些404源,例如页面包含任何JS文件,但该文件不存在于该位置,则对于URL来说将会有问题,因此此API将抛出异常。 - Freak
1
很不幸,你建议的库非常慢(渲染页面需要约40秒,而在普通浏览器上只需1秒!) - Konrad G

0

解决该问题的简单方法。 你好,你可以使用HtmlUnit这个Java API,我认为它能够帮助您访问执行的JavaScript内容,就像简单的HTML一样。

WebClient webClient = new WebClient();
HtmlPage myPage = (HtmlPage) webClient.getPage(new URL("YourURL"));
System.out.println(myPage.getVisibleText());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接