什么是 Jsoup
Jsoup :是处理 Html网页的 Java 工具库。针对 Html 5 DOM方法和 CSS选择器提供了非常方便的API,可以便捷的获取 URL 返回内容的提取和相关数据操作。
Jsoup 主要实现一下功能:
- 从 URL、文件或字符串中抓取和解析 HTML
- 使用 DOM 遍历或 CSS 选择器查找和提取数据
- 操作HTML 元素、属性和文本
- 根据安全列表清理用户提交的内容,以防止XSS攻击
- 输出整洁的 HTML
Jsoup使用
引入 Jsoup 依赖引入,历史版本
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.13.1</version>
</dependency>
加载 Html 文档方式
- URL 方式加载
// 创建URL连接 设置 超时时间、header、cookie等相关信息
Connection connection = Jsoup.connect("http://fundf10.eastmoney.com/jbgk_009265.html")
.timeout(3000)
.header("key","value")
.cookie("c1","****");
// get请求
Document docGetReq = connection.get();
// post 请求时需要通过 postDataCharset()方法设置传递参数信息
Document docPostReq = connection.post();
- 文件方式加载
// 加载Html文件
File f = new File("1.html");
Document doc = Jsoup.parse(f, "UTF-8");
Element body = doc.body();
- String 字符串方式加载
// 建议采用前两种方式进行Html网页的解析
String html = "<html><head><title>First parse</title></head>"
+ "<body><p>Parsed HTML into a doc.</p></body></html>";
Document doc = Jsoup.parse(html);
Html 文档分析
对 Html 进行分析时,一般是将获取到的信息转换为 Document (文档) 。 Html 标签存在严格的层次对应关系,索引解析时是按照这个层级进行层层解析。可以根据某一层次的定位,获取当前层次对应的上一层级或者下一层级关系,方便快速的获取到 Document 中的层级中的 元素信息。
通过DOM进行数据提取
File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");
// 根据 id 获取文档中的内容信息
Element content = doc.getElementById("content");
// 获取 'a' 标签中的元素信息
Elements links = content.getElementsByTag("a");
for (Element link : links) {
// 获取超链接路径
String linkHref = link.attr("href");
// 获取文本信息
String linkText = link.text();
}
寻找元素
寻找元素
-
getElementById(String id) :根据标签中的 id 获取元素,如果存在多个id值一样,则在不同的地方解析时将会获取到当前节点下最近 id 的结果值
-
getElementsByTag(String tag): 根据 Html 中的标签获取元素
-
getElementsByClass(String className) : 根据 class 名称获取元素
-
getElementsByAttribute(String key) :根据具体属性的 key 获取元素
-
元素相邻层级(兄弟层级)
- siblingElements() :同层级元素列表
- firstElementSibling():同层级的第一个元素节点
- lastElementSibling():同层级的最后一个元素节点
- nextElementSibling():当前层级下的同一层级中的所有同一层级的元素列表,如AB(1,2,3)C中当前层级为A,获取的是B层级中 1,2,3 的层级列表
- previousElementSibling():跟 nextElementSibling() 类似,如AB(1,2,3)C中当前层级为 1,获取的是1层级的上一个层级的A,B,C 层级列表
元素数据获取
- attr(String key) :获取属性为key的值
- attr(String key, String value):修改属性key的值为value
- attributes():获取所有属性
- text():获取标签的文本内容 , text(String value) : 设置文本内容
- ownText() :获取当前节点的文本内容
- tag() :获取标签的tag名称, tagName(String key):修改标签的名称为key
- html() html(String value):同上
- outerHtml() : 获取 外部Html 值
操作Html 和文本(在现有的Html 文件中追加部分内容信息)
- append(String html), prepend(String html)
- appendText(String text), prependText(String text)
- appendElement(String tagName), prependElement(String tagName)
- html(String value)
通过 Selector 进行数据提取
通过 Selector 选择器,可以方便的从Html 中的 CSS 或类似 Jquery 的选择器语法中查找和操作元素。
File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");
Elements links = doc.select("a[href]"); // a with href
Elements pngs = doc.select("img[src$=.png]");
// img with src ending .png
Element masthead = doc.select("div.masthead").first();
// div with class=masthead
Elements resultLinks = doc.select("h3.r > a"); // direct a after h3
选择器概述
tagname: 按标签查找元素,例如ans|tag: 在命名空间中通过标签fb|name查找<fb:name>元素,例如查找元素#id: 通过 ID 查找元素,例如#logo.class: 按类名查找元素,例如.masthead[attribute]: 具有属性的元素,例如[href][^attr]: 具有属性名称前缀的[^data-]元素,例如查找具有 HTML5 数据集属性的元素[attr=value]: 具有属性值的元素,例如[width=500](也可引用,如[data-name='launch sequence'])[attr^=value],[attr$=value],[attr*=value]: 具有以该值开头、以该值结尾或包含该值的属性的元素,例如[href*=/path/][attr~=regex]: 属性值与正则表达式匹配的元素;例如img[src~=(?i).(png|jpe?g)]*: 所有元素,例如*
选择器组合
el#id: 带有 ID 的元素,例如div#logoel.class: 具有类的元素,例如div.mastheadel[attr]: 具有属性的元素,例如a[href]- 任何组合,例如
a[href].highlight ancestor child:从祖先继承下来的子元素,例如在类“body”的块下的任何位置.body p查找p元素parent > child: 直接从父元素下降的子元素,例如div.content > p查找p元素;并body > *找到 body 标签的直接子代siblingA + siblingB: 查找紧跟在兄弟 A 之前的兄弟 B 元素,例如div.head + divsiblingA ~ siblingX: 查找兄弟 A 前面的兄弟 X 元素,例如h1 ~ pel, el, el: 对多个选择器进行分组,找到与任何选择器匹配的唯一元素;例如div.masthead, div.logo
伪选择器
:lt(n): 查找同级索引(即它在 DOM 树中相对于其父级的位置)小于 的元素n;例如td:lt(3):gt(n): 查找同级索引大于 的元素n;例如div p:gt(2):eq(n): 查找同级索引等于 的元素n;例如form input:eq(1):has(selector): 查找包含与选择器匹配的元素的元素;例如div:has(p):not(selector): 查找与选择器不匹配的元素;例如div:not(.logo):contains(text): 查找包含给定文本的元素。搜索不区分大小写;例如p:contains(jsoup):containsOwn(text): 查找直接包含给定文本的元素:matches(regex): 查找文本与指定正则表达式匹配的元素;例如div:matches((?i)login):matchesOwn(regex): 查找自身文本与指定正则表达式匹配的元素- 【注意】上述索引伪选择器是基于 0 的,即第一个元素在索引 0 处,第二个元素在 1 处,以此类推
【参考文档】