HtmlUnit + Jsoup
背景
在开发爬虫进行动态规则抓取数据时遭遇HtmlUnit无法通过登录后cookie进行访问的情况,网上一系列文章千篇一律无效;
HtmlUnit
可以理解为沙盒浏览器,会获得整个网页最终展示代码(包含动态加载数据的js),人眼所见即所得
Jsoup
只能获取网页内容(不包含js执行后的动态内容部分),优势在于可通过Jquery选择器进行摘取元素,例如#id、.class等,htmlUnit只能是document原生js摘取
问题描述
htmlUnit Code
/** HtmlUnit请求web页面 */
WebClient wc = new WebClient(BrowserVersion.CHROME);
wc.getOptions().setUseInsecureSSL(true);
wc.getOptions().setJavaScriptEnabled(true); // 启用JS解释器,默认为true
wc.getOptions().setCssEnabled(false); // 禁用css支持
wc.getOptions().setThrowExceptionOnScriptError(false); // js运行错误时,是否抛出异常
wc.getOptions().setTimeout(10 * 1000); // 设置连接超时时间 ,这里是10S。如果为0,则无限期等待
wc.waitForBackgroundJavaScript(10 * 1000); // 等待js后台执行30秒
wc.getOptions().setDoNotTrackEnabled(false);
//其他文章一贯的cookie设置方式-无效
//wc.getCookieManager().addCookie(new Cookie("domain域名","JSESSIONID","11"));
//改为以下方式
wc.addCookie("Cookie value长串不需要切割",new URL("目标网址"),"domain域名");
HtmlPage page = wc.getPage("目标网址");
另外遇到以下棘手问题(未解决)
- net.sourceforge.htmlunit.corejs.javascript.Undefined
- 场景:需要动态执行目标网站内的函数,
- 默认不指定行数会在第一行执行,由于js顺序化执行会出现未定义错误
- 源码:return this.executeJavaScript(sourceCode, “injected script”, 1);
//失败:通过改变支持ajax支持方式
wc.setAjaxControllr(new NicelyResynchronizingAjaxController());
//失败:循环判断内容,增加js-ajax执行时间
for (int i = 0; i < 20; i++) {
if (!page.getByXPath("//a[@class='font14 black']").isEmpty()) {
break;
}
synchronized (page) {
page.wait(5000);
}
}
//失败:设置执行插入的指定js行数
ScriptResult scriptResult = page.executeJavaScript("xx('x');","injected script",1000);
System.out.println(scriptResult.getJavaScriptResult());
HtmlPage newPage =(HtmlPage) scriptResult.getNewPage();
- 死活不能获取js加载后的页面,js为ajax请求
- 全网各种方式都进行尝试了
解决了的大佬可以留言下,虽然估计那时候我已经不需要了,也可以留给后来人看看~~