解析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);
	}

}