解析HTML数据,有两种工具(jsoup 和 htmlparser),在此只讲解jsoup的使用。jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。使用时,要导入jsoup-1.10.3.jar。
1. 写入HTML,相信大家都会,在此不用讲解。
2. 修改HTML
E:/MyEclipse/html/message.html 修改前:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>HTML Demo</title>
</head>
<body>
<form action="表单验证.html" method="post" id="f">
<input class="i" type="text" name="name" value="赵凯鹏">
<input class="i" type="password" name="pass" value="123456">
<input class="i" type="submit" value="登录">
</form>
<div>
<img src="https://www.baidu.com/img/bd_logo1.png" width="100px" height="50px">
<a href="https://www.baidu.com/" target="_blank">百度</a>
</div>
<table border="2" width="400px" cellpadding="10" cellspacing="0" bgcolor="aqua">
<tbody>
<tr>
<td colspan="3" align="center">星期一菜谱</td>
</tr>
<tr>
<td rowspan="2" align="center">荤菜</td>
<td id="y" align="center">鱼香肉丝</td>
<td id="c" align="center">油焖大虾</td>
</tr>
<tr>
<td align="center">海参鲍鱼</td>
<td align="center">龙肝凤胆</td>
</tr>
</tbody>
</table>
</body>
</html>
package htmlTest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
public class HtmlModify {
public static void main(String[] args) {
Document doc = null;
// 从字符串加载Document ------------------------------------------------------------
// String html = "<form action='表单验证.html' method='post'><input type='text' name='name' value='赵凯鹏' /><input type='password' name='pass' value='123456' /><input type='submit' value='登录' /><font>font</font></form>";
// doc = Jsoup.parse(html);
// Element form = doc.select("form").get(0);
/* 1.设置属性 */
//修改action
// form.attr("action", "666888");
// System.out.println(form);
//添加class
// form.addClass("f");
// System.out.println(form);
//移除class
// form.removeClass("f");
// System.out.println(form);
//移除method
// form.removeAttr("method");
// System.out.println(form);
//使用连写方式, 同时修改多处
// form.addClass("form666").attr("method", "get").removeAttr("action");
// System.out.println(form);
/* 2.设置元素的HTML内容 */
// 2.1 html(String html): 先清除元素中的HTML内容,然后用传入的HTML代替。
// form.html("<a href='https://www.hao123.com'></a>");
// System.out.println(form);
// 2.2 prepend(String first) 和 append(String last) 方法用于在分别在元素内部HTML的前面和后面添加HTML内容
// form.prepend("<a href='https://www.hao123.com'></a>");
// form.append("<a href='https://www.baidu.com'></a>");
// System.out.println(form);
// 2.3 wrap(String around) 对元素包裹一个外部HTML内容。
// Element font = form.select("font").get(0);
// font.wrap("<a herf='www.haobuhao'></a>");
// System.out.println(form);
/* 3.设置元素的文本内容 */
// text(String text) 先清除元素内部HTML内容,再进行代替
// Element font = form.select("font").get(0);
// font.text("font link");
// System.out.println(font);
// prepend(String first) 和 append(String last) 将分别在元素的内部html前、后添加文本节点
// font.prepend("前面添加文本");
// font.append("后面添加文本");
// System.out.println(form);
/* 4.设置元素 */
// Element font = form.select("font").get(0);
// font.prependElement("p");
// font.appendElement("a");
// System.out.println(form);
// 从文件加载Document ------------------------------------------------------------
//读文件
File file = new File("E:/MyEclipse/html/message.html");
try {
doc = Jsoup.parse(file, "UTF-8", "http://example.com/"); //parse(File in, String charsetName)
} catch (IOException e) {
e.printStackTrace();
}
//修改数据
doc.select("[value=赵凯鹏]").get(0).attr("value", "小赵");
doc.select("[type=submit]").get(0).attr("value", "注册");
System.out.println(doc);
//保存修改到原文件【注意: 封装的流不能设置编码】
FileOutputStream fos = null;
OutputStreamWriter ow = null;
try {
fos = new FileOutputStream(file, false);
ow = new OutputStreamWriter(fos , "utf-8");
ow.write(doc.toString());
ow.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
ow.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("write success");
}
}
E:/MyEclipse/html/message.html 修改后:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>HTML Demo</title>
</head>
<body>
<form action="表单验证.html" method="post" id="f">
<input class="i" type="text" name="name" value="小赵">
<input class="i" type="password" name="pass" value="123456">
<input class="i" type="submit" value="注册">
</form>
<div>
<img src="https://www.baidu.com/img/bd_logo1.png" width="100px" height="50px">
<a href="https://www.baidu.com/" target="_blank">百度</a>
</div>
<table border="2" width="400px" cellpadding="10" cellspacing="0" bgcolor="aqua">
<tbody>
<tr>
<td colspan="3" align="center">星期一菜谱</td>
</tr>
<tr>
<td rowspan="2" align="center">荤菜</td>
<td id="y" align="center">鱼香肉丝</td>
<td id="c" align="center">油焖大虾</td>
</tr>
<tr>
<td align="center">海参鲍鱼</td>
<td align="center">龙肝凤胆</td>
</tr>
</tbody>
</table>
</body>
</html>
3. 读取HTML
package htmlTest;
import java.io.File;
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class HtmlRead {
public static void main(String[] args) {
Document doc = null;
/* 从字符串加载Document */
// String html = "<html><head><title>HTML Demo</title></head><body><p>中华人民共和国</p></body></html>";
// doc = Jsoup.parse(html);
/* 从URL加载Document */
// try {
// doc = Jsoup.connect("https://www.hao123.com").get();
// } catch (IOException e) {
// e.printStackTrace();
// }
/* 从文件加载Document */
File input = new File("E:/MyEclipse/html/message.html");
try {
doc = Jsoup.parse(input, "UTF-8", "http://example.com/"); //parse(File in, String charsetName)
} catch (IOException e) {
e.printStackTrace();
}
// 1.DOM方式遍历
// System.out.println(doc.toString());
// System.out.println("---------------------------");
// System.out.println(doc.title());
// System.out.println(doc.baseUri()); //文档绝对路径
//
// Element form = doc.getElementById("f");
// Attributes attrList = form.attributes();
// System.out.println(form.id());
// System.out.println(form.tagName()+" "+attrList.html());
//
// Elements eleList = doc.getElementsByTag("input");
// for(int i=0; i<eleList.size(); i++){
// Element element = eleList.get(i);
// System.out.println("type="+element.attr("type"));
// System.out.println("name="+element.attr("name"));
// System.out.println("value="+element.attr("value"));
// }
//-------------------------------------------------------------------------------------------
// 2.选择器方式遍历【jQuery选择器参考:W3CSchool jQuery 参考手册 - 选择器 && jQuery PPT】
//基本选择器
// System.out.println(doc.select("#f").get(0).tagName()); //#id
// System.out.println(doc.select(".i").get(1).toString()); //.class
// System.out.println(doc.select("a").get(0).toString()); //标签名
//属性选择器
// System.out.println(doc.select("[href]").get(0).toString()); //含有属性herf的元素
// System.out.println(doc.select("[type=submit]").get(0).toString()); //属性type=submit的元素
// System.out.println(doc.select("[colspan!=2]").get(0).toString()); //属性colspan!=2的元素
//
// System.out.println(doc.select("[^al]").get(0).toString()); //属性是以al开头的元素
// System.out.println(doc.select("[type^=s]").get(0).toString()); //属性type是以s开头的元素
// System.out.println(doc.select("[value$=鹏]").get(0).toString()); //属性value是以鹏结束的元素
// System.out.println(doc.select("[value*=4]").get(0).toString()); //属性value包含4的元素
// System.out.println(doc.select("[class][type=submit]").get(0).toString());//同时满足多个属性的元素
//组合选择器
// System.out.println(doc.select("form#f").get(0).toString()); //el#id
// System.out.println(doc.select("input.i").get(0).toString()); //el.class
// System.out.println(doc.select("td[rowspan]").get(0).toString()); //el[attr]
// System.out.println(doc.select("input[name].i").get(0).toString()); //el[attr].class
//
// System.out.println(doc.select("tr td").get(1).toString()); //选择器1 选择器2 ==> 后代元素
// System.out.println(doc.select("div > [src]").get(0).toString()); //选择器1 > 选择器2 ==> 子代元素
// System.out.println(doc.select("[rowspan] + #y").get(0).toString()); //选择器1 + 选择器2 ==> 1元素之后紧挨的同级元素2
// System.out.println(doc.select("[rowspan] ~ #y").get(0).toString()); //选择器1 ~ 选择器2 ==> 1元素之后所有同级元素2
// System.out.println(doc.select("[rowspan],#y,#c").get(2).toString()); //选择器1 , 选择器2 , 选择器3 ==> 匹配1元素 、元素2、元素3中的任一个
//伪类选择器
/*
first()或:first 获取第一个元素 单个元素
last()或:last 获取最后一个元素 单个元素
:not(selector) 获取除过给定选择器之外的元素 元素集合,如:$("li:not(.title)")获取class不是title的li元素
:even 获取索引值为偶数的元素,索引号从0开始 元素集合
:odd 获取索引值为奇数的元素,索引号从0开始 元素集合
:eq(index) 获取索引值等于index的元素,索引号从0开始 单个元素,如:$("li:eq(1)")获取索引等于1的<li>元素
:gt(index) 获取索引值大于index的元素,索引号从0开始 元素集合,如:$("li:gt(1)")获取索引大于1的<li>元素
:lt(index) 获取索引值小于index的元素,索引号从0开始 元素集合,如:$("li:lt(1)")获取索引小于1的<li>元素
:header 获取所有标题元素,如h1~h6 元素集合
:animated 获取正在执行动画效果的元素 元素集合
:contains(text) 获取含有文本内容为text的元素 元素集合
:empty 获取不包含后代元素或文本的元素 元素集合
:has(selector) 获取含有后代元素为selector的元素 元素集合
:parent 获取含有后代元素或文本的元素 元素集合
*/
/* 处理URLs : 你有一个包含相对URLs路径的HTML文档,需要将这些相对路径转换成绝对路径的URLs */
try {
doc = Jsoup.connect("https://www.hao123.com").get(); //从URL获得HTML Document
} catch (IOException e) {
e.printStackTrace();
}
Element link = doc.select("a").first();
String relHref = link.attr("href");
String absHref = link.attr("abs:href"); //Node.attr("abs:href") == Node.absUrl("href")
System.out.println(relHref);
System.out.println(absHref);
}
}