HtmlUnit 使用记录 ---- 无顺序记录

最近需要解析javascript动态生成的内容,Jsoup不能够完成这个功能,就使用HtmlUnit,可以说到目前为止HtmlUnit很好的完成了任务。


但是有时候会出现莫名其妙的问题,现在将处理js请求内容中遇到的问题和解决方法列举如下。等手头这个项目做完了会把htmlunit的使用系统的做出总结。


第一类,通过源码就能够看到js请求,并且模拟请求获取内容


比如这个网站:http://fashion.qq.com/a/20140403/011113.htm ;    //吴莫愁

要获取所有图片,必须依次单击下一页,通过源码看不到内容,但是通过审查元素可以发现其下一页的内容是通过这几行代码获得:



于是在代码里可以这样写:

rootPage.executeJavaScript("myGallery.changeImage("+ i +")") ;
rootPage.executeJavaScript("javascript:void(0)") ;

rootPage对象是htmlunit的webclient.getPage(url)返回的对象


再下一步通过:

rootPage.asXml() ;

就可以看到结果,这时候rootPage对象的内容已经发生了改变。


第二类,没有onclick方法 比如这个网页:

http://fashion.qq.com/a/20140402/005443.htm //平胸美女

通过审查元素查看:



通过模拟this.blur() 和 javascript:void(0) 都不能获取下一页的内容。


要么就一步一步查看他的js调用,通过查看js源码。要么就是观察其浏览器地址改变。通过观察可以发现每一次请求下一页他的浏览器地址就改变:

http://fashion.qq.com/a/20140402/005443.htm#p=1

http://fashion.qq.com/a/20140402/005443.htm#p=2

http://fashion.qq.com/a/20140402/005443.htm#p=3 ...

所以可以通过手动拼凑他的URL地址的方法来获取下一页的内容。


这个方法不是正统的解决方法,但是目前可以解决问题。回头会继续研究。


第三种,就是有onclick方法,但是href方法不能使用,并且浏览器地址跳转也无规律。

比如这个: http://korea.yule.sohu.com/s2009/koreanews/index.shtml //韩娱新闻

要想请求他的下一页内容,通过审查元素查看:



他的href属性指向的地址始终是第一页,所以如果再调用

rootPage.executeJavaScript("javascript:go(2)") ;
rootPage.executeJavaScript("#") ;

始终会返回第一页,实际上我试了很多方法,都解决不了。


后来发现htmlUnit有一个page对象,而page对象可以返回其url,这样的话就可以得到他的请求后的新的url。然后再重新请求url就可以得到下一页内容。


代码如下:

ScriptResult sr = rootPage.executeJavaScript("javascript:go(x)") ;
Page page2 = sr.getNewPage() ;
System.out.println(page2.getUrl().toString());

x变量表示第几页


还有一种方法,因为每次executeJavaScript方法执行后都建立了一次请求了,所以如果只拿到url再次进行请求比较浪费资源,可以使用这种办法:
ScriptResult sr = rootPage.executeJavaScript("javascript:go("+ i +")") ;
Page page2 = sr.getNewPage() ;
WebResponse wr = page2.getWebResponse() ;
String content = wr.getContentAsString() ;

这个时候content对象里面是页面经过执行js之后的完全代码,只要把这些内容放进html的txt文件里就可以使用了。

下一步可以使用jsouop的parse方法,以content为参数,获取jsoup的document对象,就更容易操作了。



如果只想要看到执行js之后生成的代码,比如这个网站:
http://beauty.rayli.com.cn/makeup/master/index.shtml

他的下一页的内容整个标签和内容都是由js生成的。如图


这个时候没有onclick方法来获取下一页内容,就只能模拟js代码获取他生成的下一页的地址。所以使用这几行代码生成:

ScriptResult sr = rootPage.executeJavaScript("pagelist["+i+"]") ;
Object o = sr.getJavaScriptResult() ; //执行过后的结果

System.out.println(o.toString());

输出结果为:makeup/master/list_1.shtml

makeup/master/list_2.shtml

makeup/master/list_3.shtml 


注意这里的结果是相对地址,不是绝对地址。要获的绝对地址也可以,通过java的URL对象。代码如下:


URL u = new URL(url) ;
String baseURL = "http://" + u.getHost() ;

String absURL = baseURL + o.toString() ;

这里的absURL就是绝对地址,放进浏览器里可以直接获取下一页的内容。


再遇到更复杂的情况再做说明

OVER

htmlunit-core-js 是一个基于 Rhino JavaScript 引擎的 JavaScript 引擎,它可以帮助你在 Java 应用程序中运行 JavaScript 代码。下面是一个简单的示例,演示如何使用 htmlunit-core-js 运行 JavaScript 代码: ```java import org.mozilla.javascript.Context; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.html.HtmlPage; public class HtmlUnitCoreJsExample { public static void main(String[] args) throws Exception { // 创建一个 JavaScript 引擎上下文 Context context = Context.enter(); try { // 创建一个顶级作用域对象 Scriptable scope = context.initStandardObjects(); // 将一个 Java 对象添加到 JavaScript 环境中 Object wrappedOut = Context.javaToJS(System.out, scope); ScriptableObject.putProperty(scope, "out", wrappedOut); // 执行一段 JavaScript 代码 String script = "var message = 'Hello, world!'; out.println(message);"; context.evaluateString(scope, script, "example", 1, null); // 使用 HTMLUnit 来执行 JavaScript 代码 WebClient webClient = new WebClient(); HtmlPage page = webClient.getPage("https://www.baidu.com/"); String pageTitle = (String) context.evaluateString(scope, "document.title", "example", 1, null); System.out.println("Page title: " + pageTitle); } finally { // 释放 JavaScript 引擎上下文 Context.exit(); } } } ``` 这个示例包括以下步骤: 1. 创建一个 JavaScript 引擎上下文。 2. 创建一个顶级作用域对象,并将一个 Java 对象添加到 JavaScript 环境中。 3. 执行一段 JavaScript 代码,将输出打印到控制台。 4. 使用 HTMLUnit 库加载一个网页,并在 JavaScript 引擎环境中获取页面标题。 5. 释放 JavaScript 引擎上下文。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值