在我们抓取到页面之后,还需要对页面进行解析。整个页面都是字符串的形式,可以使用字符串处理工具来解析页面,也可以使用正则表达式,但这些方法都会带来很大的开发成本。所以我们需要一款准们解析 html 页面的工具。
Jsoup
jsoup是一款 java 的 HTML 解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
主要功能:
- 从URL,文件或字符串中解析HTML;
- 使用DOM 或 CSS选择器来查找、取出数据;
- 可操作 HTML元素、属性、文本(基本不使用)
使用
1. 导入依赖坐标(jsoup、commons-io、commons-lang3)
2.测试代码
2.1 解析URL
@Test
public void urlFun() throws Exception {
// 解析URL地址,参数:访问的url,访问时的超时时间
Document doc = Jsoup.parse(new URL("http://112.124.1.187/"),10000);
// 使用标签选择器
String title = doc.getElementsByTag("title").first().text();
System.out.println(title);
}
ps: 这里我们可以得出,Jsoup 可以代替 HttpClient 直接发起请求数据。但是我们往往不会这么做,因为实际开发中,需要使用到多线程、连接池、代理等等,而 Jsoup 对这些的支持并不是很好,所以我们一般把 Jsoup 仅仅作为 html 解析工具使用。
2.2 解析字符串
@Test
public void strFun() throws Exception {
// 从文件获取字符串
String content = FileUtils.readFileToString(new File("C:\\Users\\24360\\Desktop\\a.html"),"utf-8");
// 解析字符串
Document doc = Jsoup.parse(content);
// 使用标签选择器
String title = doc.getElementsByTag("title").first().text();
System.out.println(title);
}
2.3. 解析文件
@Test
public void strFun() throws Exception {
// 解析文件
Document doc = Jsoup.parse(new File("C:\\Users\\24360\\Desktop\\a.html"),"gbk");
// 使用标签选择器
String title = doc.getElementsByTag("title").first().text();
System.out.println(title);
}
3.使用 dom 解析
@Test
public void domTest() throws IOException {
// 解析文件,获取Document对象
Document doc = Jsoup.parse(new File("C:\\Users\\24360\\Desktop\\a.html"),"gbk");
// 1.根据id获取元素: getElementById
Element element1 = doc.getElementById("header");
// System.out.println(element1.text());
// 2.根据标签获取元素: getElementsByTag
Element element2 = doc.getElementsByTag("span").get(2);
System.out.println(element2.text());
// 3.根据class获取元素: getElementsByClass
Element element3 = doc.getElementsByTag("class_a").get(0);
System.out.println(element3.text());
// 4.根据属性获取元素: getElementsByAttribute
Element element4 = doc.getElementsByTag("href").get(0);
System.out.println(element4.text());
// 4.2 如果有多个属性名相同的情况,也可以根据属性-值 来获取
Element element5 = doc.getElementsByAttributeValue("href","http://www.baidu.com").get(0);
System.out.println(element5.text());
}
4. 从元素中获取数据
如:
<a id="baidu" class="class_a class_b" href="http://www.baidu.com">百度</a>
@Test
public void attrTest() throws IOException {
// 解析文件,获取Document对象
Document doc = Jsoup.parse(new File("C:\\Users\\24360\\Desktop\\a.html"),"gbk");
// 1.根据id获取元素: getElementById
Element ele = doc.getElementById("baidu");
// 元素中获取数据
// 1.元素中获取id
String strId = ele.id();
System.out.println(strId); // baidu
// 2.元素中获取类名
String className = ele.className();
System.out.println("所有类名:" + className); // 所有类名:class_a class_b
Set<String> classSet = ele.classNames();
for(String s : classSet){ // class_a class_b
System.out.println(s);
}
// 3.元素中获取对应属性的值
String attr = ele.attr("href"); //http://www.baidu.com
System.out.println(attr);
// 4 获取所有属性
Attributes attrs = ele.attributes();
System.out.println(attrs.toString()); // id="baidu" class="class_a class_b" href="http://www.baidu.com"
}
5.Selector 选择器
tagname
:通过标签查找元素,例:span;
#id
:通过id查找元素,例:#group;
.class
:通过类名查找元素,例:.class_a;
[attribute]
:通过属性查找元素,例:[abc];
[attr=value]
:通过属性值查找元素,例:[class=sn];
如:
<a id="baidu" class="class_a class_b" href="http://www.baidu.com">百度</a>
属性值
5.1 使用 Selector 选择器
@Test
public void selectorTest() throws IOException {
// 解析文件,获取Document对象
Document doc = Jsoup.parse(new File("C:\\Users\\24360\\Desktop\\a.html"),"gbk");
// tagname:通过标签查找元素,例:span
Element e1 = doc.select("a").get(0);
System.out.println(e1.text()); // 百度
// #id:通过id查找元素,例:#baidu
Element e2 = doc.select("#baidu").get(0);
System.out.println(e2.text()); // 百度
// .class:通过类名查找元素,例:.class_a
Element e3 = doc.select(".class_a").get(0);
System.out.println(e3.text()); // 百度
// [attribute]:通过属性查找元素,例:[abc]
Element e4 = doc.select("[abc]").get(0);
System.out.println(e4.text()); // 属性值
// [attr=value]:通过属性值查找元素,例:[abc=123]
Element e5 = doc.select("[abc=123]").get(0);
System.out.println(e5.text()); // 属性值
}
5.2 Selector 选择器组合使用
el#id
:元素+ID,例:h3#group
el.class
:元素+类名,例:h3.class_a
el[attr]
:元素+属性名,例:span[abc]
任意组合
:例:span[abc].class_a
ancestor child
:查找某个元素下子元素,例:.class_a li,查找“.class_a”下的所有li
parent > child
:查找某个父元素下的直接子元素(第一级)
parent > *
:查找某个父元素下的所有直接子元素