htmlunit 是一款开源的java 页面分析工具,读取页面后,可以有效的使用htmlunit分析页面上的内容。项目可以模拟浏览器运行,被誉为java浏览器的开源实现。是一个没有界面的浏览器,运行速度迅速。是junit的扩展之一,采用的是Rhinojs引擎。模拟js运行
1.HTMLUNIT的基本功能展示
首先我们新建一个Maven普通客户端项目,然后打开pom.xml
引入htmlunit支持:
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.26</version>
</dependency>
然后我们写一个测试类,来解析www.baidu.com 获取网页html以及网页文本,这里有点类似httpClient,但是底层执行过程默认多了一个js执行过程(当然htmlunit提供了关闭js解析设置);
import java.io.IOException;
import java.net.MalformedURLException;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class HtmlUnitTest {
public static void main(String[] args) {
WebClient webClient=new WebClient(); // 实例化Web客户端
try {
HtmlPage page=webClient.getPage("http://www.baidu.com"); // 解析获取页面
System.out.println("网页html:"+page.asXml()); // 获取Html
System.out.println("====================");
System.out.println("网页文本:"+page.asText()); // 获取文本
} catch (FailingHttpStatusCodeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
webClient.close(); // 关闭客户端,释放内存
}
}
}
前面我们的测试代码是直接请求的,有些网站服务器防火墙会直接拒绝访问。
我们现在用htmlunit来模拟下浏览器请求;主要是加了一些头消息;
这个是我们用火狐调试工具看到的请求头小心里的属性,当然上面还有返回的头消息;
我们用htmlunit可以模拟浏览器执行,内置的可以模拟IE,火狐,谷歌;
WebClient构造方法里有个重载方法,可以加一个指定版本属性;
完整代码:
import java.io.IOException;
import java.net.MalformedURLException;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class HtmlUnitTest {
public static void main(String[] args) {
WebClient webClient=new WebClient(BrowserVersion.FIREFOX_52); // 实例化Web客户端
try {
HtmlPage page=webClient.getPage("http://www.java1234.com"); // 解析获取页面
System.out.println("网页html:"+page.asXml()); // 获取Html
System.out.println("====================");
System.out.println("网页文本:"+page.asText()); // 获取文本
} catch (FailingHttpStatusCodeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
webClient.close(); // 关闭客户端,释放内存
}
}
}
htmlunit 提供了丰富的api来获取指定元素 jsoup有的 htmlunit也有;
我们这里举例:
import java.io.IOException;
import java.net.MalformedURLException;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.DomNodeList;
import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlListItem;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class HtmlUnitTest2 {
public static void main(String[] args) {
WebClient webClient=new WebClient(BrowserVersion.FIREFOX_52); // 实例化Web客户端
try {
HtmlPage page=webClient.getPage("http://www.baidu.com");
HtmlDivision div=page.getHtmlElementById("navMenu"); // 查找指定id的html dom元素
System.out.println(div.asXml());
System.out.println("======================");
DomNodeList<DomElement> aList=page.getElementsByTagName("a"); // 根据tag名称查询所有tag
for(int i=0;i<aList.getLength();i++){
DomElement a=aList.get(i);
System.out.println(a.asXml());
}
System.out.println("======================");
HtmlListItem item =(HtmlListItem) page.getByXPath("//div[@id='navMenu'][1]/ul/li").get(0); // xpath方式
System.out.println(item.asXml());
} catch (FailingHttpStatusCodeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
webClient.close();
}
}
}
有时候频繁的爬取第三方站点内容,会被站点的防火墙拦截,IP拉黑,所以这时候,就要用到代理IP,拉黑一个就换一个;
htmlunit实用代理的方式比较简单,WebClient重载构造方法就有提供,我们看下演示代码:
import java.io.IOException;
import java.net.MalformedURLException;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class HtmlUnitTest3 {
public static void main(String[] args) {
WebClient webClient=new WebClient(BrowserVersion.FIREFOX_52,"202.106.16.36",3128); // 实例化Web客户端
try {
HtmlPage page=webClient.getPage("http://www.baidu.com"); // 解析获取页面
System.out.println("网页html:"+page.asXml()); // 获取Html
System.out.println("====================");
System.out.println("网页文本:"+page.asText()); // 获取文本
} catch (FailingHttpStatusCodeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
webClient.close(); // 关闭客户端,释放内存
}
}
}