htmlunit,用于网站单元测试的,在它的主页,介绍说“是一款没有图形界面的浏览器”,可以做浏览器做的很多事情,比如浏览页面、填充表单、模拟点击按钮等等。优点有:
- 支持javascript
- 可模拟多种浏览器,如firefox、ie6/7/8
- 建立在httpclient之上,简化了很多,接口更清晰和直接
当然,它不是真正的浏览器,还是有一些缺陷,如对javascript的支持没有浏览器那么全面,这个项目一直在持续中,相信以后会有更好的支持。
htmlunit的初衷是用于验证网站开发中页面UI上的功能正确性,一直以来,页面UI的测试都脱离不了测试人员通过肉眼来验证是否正确,这样的效率很低,也很可能出错,利用htmlunit,一方面可以自动化测试,一方面减少了人力方面的资源,一举两得。
换个角度思考,既然htmlunit可以用来验证,当然也可以用于其他方面。很明显的一点,就是可以用来做网络爬虫,这几年web2.0概念如火如荼,很多网站都大量采用了AJAX技术,动态加载页面内容,导致传统的网络爬虫抓瞎,因为传统的网络爬虫不支持javascript,抓取的页面都是动态加载前的内容,而htmlunit通过javascript的支持,应该可以取得更好的结果。
另外一点,可以用来模拟很多行为。比如模拟登录邮箱,将邮件读取显示出来,这样不用打开浏览器或邮件客户端即可以读到最新的邮件,或者模拟登录开心农场,定时去收菜或偷菜,此类网页游戏的外挂,使用htmlunit写起来应该不是很困难的事情。
参考:
- htmlunit主页
httpclient是由java实现用来模拟http请求的,开源的,现在已经出到4.1版本了,改动太大了,还是之前的3.1版本比较符合人的思维,主要讲下使用中遇到的问题。
一、编码
编码有好几块,一个是客户端发起请求时指定的编码,一个是服务器返回的编码,还有一个是返回页面的Content-Type里指定的编码,一般来说后两者是相同的。
对于发起请求时的编码,可以先查看网页的源码,拿到里面的编码作为请求时的编码即可。
为了获取正确的返回内容,可以采用如下:
System.out.println("response body: "+new String(method.getResponseBody(), method.getRequestCharSet()))
有些时候通过指定正确的编码还是返回乱码,有可能是由于服务端采用gzip压缩的原因,尝试在request header里去掉[Accept-Encoding,gzip,deflate]也许会返回正确的结果。
二、为get/post指定请求编码
分别继承各自的父类,然后重载getRequestCharSet,如get方法
public class EncodedGetMethod extends GetMethod {
private String charSet = "utf-8";
public EncodedGetMethod(String uri, String charset) {
super(uri);
this.charSet = charset;
}
@Override
public String getRequestCharSet() {
return this.charSet;
}
}
三、post的两种传参数方式
对于表单提交,一般有两种,带有图片,form的属性里有enctype=”multipart/form-data”;还有一种是简单的纯文本提交,如输入用户名密码然后登录的表单。
httpclient针对这两种form使用了不同的传参数方式,
1. 对于有图片的form提交使用Part[],有两种,StringPart用于传简单的文本,FilePart用于传文件,典型的StringPart如下:
StringPart sp = new StringPart(name, value, charset);
2. 对于纯文本的form提交使用NameValuePair[]
四、关于cookie
httpclient已经相当聪明了,会自动管理cookie,对于一个client发出的一系列get/post请求都享有当前的cookie。
参考:
- httpclient主页
- 关于编码
- 关于multipart表单的post方法