本文摘抄其他博客或者技术论坛,自己搜集整理如下:
HtmlUnit学习总结
htmlunit 是一款开源的java 页面分析工具,读取页面后,可以有效的使用htmlunit分析页面上的内容。项目可以模拟浏览器运行,被誉为java浏览器的开源实现。是一个没有界面的浏览器,运行速度迅速。(百度百科)
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.15</version>
</dependency>
HtmlUnit
简介:HtmlUnit
说白了就是一个浏览器,这个浏览器是用Java写的无界面的浏览器,正因为其没有界面,因此执行的速度还是可以滴,HtmlUnit
提供了一系列的API,这些API可以干的功能比较多,如表单的填充,表单的提交,模仿点击链接,由于内置了Rhinojs
引擎,因此可以执行Javascript
。
网络爬虫第一个要面临的问题,就是如何抓取网页,抓取其实很容易,没你想的那么复杂,一个开源HtmlUnit
包,4行代码就OK啦,例子如下:
final WebClient webClient=new WebClient();//创建对象
final HtmlPage page=webClient.getPage("https://www.baidu.com");//获取页面
System.out.println(page.asText());//asText() 顾名思义 获取所有文本
webClient.closeAllWindows();//关闭窗口
在程序中写上上面的4行代码,运行,就可以得到页面的全部内容,上面代码在运行的过程中会出现很多警告,出现这些警告的主要原因是由于以下两点:
1.HtmlUnit
对Javascript
的支持不是很好
2.HtmlUnit
对CSS
的支持不是很好
明白了上面的两点后,将代码重新改写一下,该禁用的就禁用,同时禁用一些不必要的功能,也有利于提高程序的运行效率,再者说网络爬虫也不需要CSS的支持
final WebClient webClient=new WebClient();
webClient.getOptions().setCssEnabled(false);//关闭css
webClient.getOptions().setJavaScriptEnabled(false);//关闭js
final HtmlPage page=webClient.getPage("https://www.baidu.com");
System.out.println(page.asText());
webClient.closeAllWindows();
重要API的使用 在介绍API的使用之前要先明白的一个问题是,WebClient,WebWindow,Page三者之间的关系,所有的页面最终都是在一个WebWindow对象里面,WebClient在创建时会自动的创建一个WebWindow对象,当调用getPage时会将新页面加载到WebWindow里,你可以理解成WebClient就是IE内核,WebWindow就是呈现页面的浏览器窗口,三者之间的关系图如下图所示:
可以模拟的浏览器有Chrome
/FireFox
/IE
//模拟chorme浏览器,其他浏览器请修改BrowserVersion.xxx常量
WebClient webClient=new WebClient(BrowserVersion.CHROME);
代理的配置很简单,只需要配置好地址,端口,用户名与密码即可
final WebClient webClient = new WebClient(BrowserVersion.CHROME,"http://127.0.0.1",8087);
final DefaultCredentialsProvider credentialsProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
credentialsProvider.addCredentials("username","password");
//获取表单
final HtmlForm form = page.getFormByName("form");
//获取提交按扭
final HtmlSubmitInput button = form.getInputByName("submit");
//一会得输入的
final HtmlTextInput textField = form.getInputByName("userid");
textField.setValueAttribute("test");
//点击提交表单
final HtmlPage page = button.click();
网络爬虫中主要目的就是获取页中所有的链接,代码如下:
List<HtmlAnchor> achList=page.getAnchors();
for(HtmlAnchor ach:achList){
System.out.println(ach.getHrefAttribute());
}
使用HtmlUnit模拟浏览器操作时,我们有时候要做一些上传文件操作。这就要利用HtmlFileInput这个类了。
通过page获得HtmlForm,再通过HtmlForm获得HtmlFileInput
HtmlForm form = page.getFormByName("form");//如果有form的话
//如果在获取HtmlForm时,发现form表单没有name属性,也可以通过下列语句获取
//HtmlForm form = page.getForms().get(0);
HtmlFileInput fileInput = form.getInputByName("fileInput");
//通过设置valueAttribute来确定上传哪个文件
fileInput.setValueAttribute("D:\\111.jpg");
//最后按下提交按钮提交
HtmlElement submitBtn = page.getElementByName("submit");
submitBtn.click();
这样就完成了一次上传文件的过程。
通过get或者XPath可以从HtmlPage中获得特定的Html元素,如下例子
1.6.1 通过get方法获取
HtmlPage page=webClient.getPage("http://www.yanyulin.info");
//从[烟雨林博客]上获取标签hed的内容
HtmlDivision div=(HtmlDivision)page.getElementById("hed");
1.6.2 通过XPath获取
XPath通常用于无法通过Id搜索或者需要更为复杂的搜索时,XPath的相关教程Xpath
//同样可以打印出hed的内容,//div中//表示搜索整个文档中的div,并将这些div
//放入list中,然后获取第一个div
final HtmlDivision div = (HtmlDivision) page.getByXPath("//div").get(0);
System.out.println(div.asXml());//asXml() 转换为xml形式
1.6.3 通过CSS选择器(Selector)获取
querySelector(String selectors) 获取匹配选择器的第一个元素
DomNodeList<DomNode> domNodeList=querySelectorAll(String selectors) 获取所有匹配选择器的元素
示例: 贴吧自动抢二楼 教程
通过CSS选择器(Selector)获取元素,代码片段如下:
(查看完整代码点击:完整代码)
// 获取当前页的所有class="i"元素。返回 DOM节点列表
DomNodeList<DomNode> iList = page.querySelectorAll(".i");
// 遍历
for(DomNode i: iList) {
// 选择 p 元素
DomNode p = i.querySelector("p");
// asText() 返回 元素文本, contains是 String的方法,查找 "回0 " 字符串
if(p.asText().contains("回0 ")) {
// 这里就是找到了 回帖为0的帖子
// 我们用 父元素 div.i 来继续获取 子元素 a 标签。
HtmlAnchor a = (HtmlAnchor)i.querySelector("a");
// 获取 a 标签的属性 href ,就是帖子详情的地址啦!!
String href = a.getAttribute("href");
System.out.println(href);
}
//1.创建对象
WebClient webClient=new WebClient(BrowserVersion.CHROME);
//2.设置参数
//启动js
webClient.getOptions().setJavaScriptEnabled(true);
//关闭css渲染
webClient.getOptions().setCssEnabled(false);
//启动重定向
webClient.getOptions().setRedirectEnabled(true);
//启动cookie管理
webClient.setCookieManager(new CookieManager());
//启动ajax代理
webClient.setAjaxController(new NicelyResynchronizingAjaxController());
//js运行时错误,是否抛出异常
webClient.getOptions().setThrowExceptionOnScriptError(false);
//3.获取页面
HtmlPage page=webClient.getPage(url);
//等待js渲染执行 waitime等待时间(ms)
webClient.waitForBackgroundJavaScript(waitime);
//4.解析页面
......
@Test
public void htmlunit(){
String str = getNextUrl("狗");
System.out.println(str);
}
/**
* 通过htmlunit来获得一些搜狗的网址。
* 通过模拟鼠标点击事件来实现
* @param key
* @return
* @throws Exception
*
* 1.HtmlUnit对Javascript的支持不是很好
2.HtmlUnit对CSS的支持不是很好
明白了上面的两点后,将代码重新改写一下,该禁用的就禁用,同时禁用一些不必要的功能,
也有利于提高程序的运行效率,再者说网络爬虫也不需要CSS的支持
*
*
* //模拟chorme浏览器,其他浏览器请修改BrowserVersion.xxx常量
WebClient webClient=new WebClient(BrowserVersion.CHROME);
*
*
*这个返回的是在搜狗上输入狗 点击搜索的操作 返回 成功后的链接
*/
public String getNextUrl(String key){
String page = new String();
try {
WebClient webClient = new WebClient();
//关闭css
webClient.getOptions().setCssEnabled(false);
//关闭js
webClient.getOptions().setJavaScriptEnabled(false);
//去拿网页
HtmlPage htmlPage = webClient.getPage("http://pic.sogou.com/");
// 获取所有文本
//System.out.println(htmlPage.asText());
//得到表单
HtmlForm form = htmlPage.getFormByName("searchForm"); //ByName 表单的name=searchForm;
//得到提交按钮
HtmlSubmitInput button = form.getInputByValue("搜狗搜索");//input 的value =搜狗搜索
//得到输入框
HtmlTextInput textField = form.getInputByName("query"); //input的name = query
//输入内容
textField.setValueAttribute(key);
//点一下按钮
HtmlPage nextPage = button.click();
String str = nextPage.toString();
page = Substr.subString(str,"(",")");
webClient.closeAllWindows();关闭窗口
} catch (Exception e) {
e.printStackTrace();
}
return page;
}