介绍:什么是 jsoup
工作中我们有时会遇到需要解析 HTML 文件的需求,比如获取某个网页的 title,favicon,某个标签的属性或内容,甚至是修改 HTML 页面等需求。如果自己编码来实现也可以,但 HTML 很复杂,自己解析会遇到各种情况需要处理。
本文介绍一个开源且功能强大的解析 HTML 的 Java 库:jsoup,简化了从 HTML 中解析数据的过程,可以解析 HTML 文件、HTML 格式的字符串,输入流、甚至提供了给定 URL 并解析返回的 HTML 页面的能力。并且 jsoup 使用的是相对宽松的 MIT 许可证。
jsoup 的主要功能:
- 从 URL、文件或字符串中抓取并解析 HTML
- 使用 DOM 遍历或 CSS 选择器查找并提取数据
- 操作 HTML 元素、属性和文本
- 清理不受信任的 HTML(以防止 XSS)
- 输出整洁的 HTML
如何使用 jsoup
这里以 Kotlin 中使用 jsoup 解析 HTML 为例进行介绍
1. 添加 Gradle 依赖项
dependencies {
implementation("org.jsoup:jsoup:1.17.2")
}
2. 从字符串中解析 HTML
使用静态 Jsoup.parse(String html)
方法解析字符串中的 HTML
val html = ("<html><head><title>First parse</title></head>"
+ "<body><p>Parsed HTML into a doc.</p></body></html>")
val doc: Document = Jsoup.parse(html)
3. 从网络获取和解析 HTML 页面
如果页面来自网络,则可以使用 Jsoup.connect(String url)
方法获取和解析 HTML 页面
val doc: Document = Jsoup.connect("https://itmob.cn").get()
获取 HTML 页面的网络请求也可以设置各种参数:
val doc: Document = Jsoup.connect("https://itmob.cn")
.userAgent("Mozilla")
.timeout(5000)
.data("name", "itmob.cn")
.get()
4. 从文件加载和解析 HTML 文档
val input = File("/tmp/input.html")
val doc = Jsoup.parse(input, "UTF-8", "https://itmob.cn/")
5. 从元素中获取属性、文本和 HTML
val html = "<p>An <a href='https://itmob.cn/'><b>example</b></a> link.</p>"
val doc = Jsoup.parse(html)
val link: Element = doc.select("a").first()
// 使用 Element.text() 方法获取元素(及其组合子元素)上的文本
val text = doc.body().text() // "An example link"
// 使用 Node.attr(String key) 方法要获取属性的值
val linkHref: String = link.attr("href") // "https://itmob.cn/"
val linkText: String = link.text() // "example""
// 使用 Element.html() 或 Node.outerHtml() 获取 HTML 节点
val linkOuterH: String = link.outerHtml() // "<a href="https://itmob.cn"><b>example</b></a>"
val linkInnerH: String = link.html() // "<b>example</b>
6. 使用 DOM 方法导航文档
Element
类提供了一系列类似 DOM 操作的方法来查找元素、提取和操作其数据
val input = File("/tmp/input.html")
val doc = Jsoup.parse(input, "UTF-8", "https://itmob.cn/")
val content = doc.getElementById("content")
val links = content.getElementsByTag("a")
for (link in links) {
val linkHref = link.attr("href")
val linkText = link.text()
}
7. 使用 CSS 选择器查找元素
jsoup 支持 CSS 选择器语法来查找匹配元素,这允许非常强大和健壮的查询
val input = File("/tmp/input.html")
val doc = Jsoup.parse(input, "UTF-8", "https://itmob.cn/")
val links = doc.select("a[href]") // 有 href 属性的 a 标签
val pngs = doc.select("img[src$=.png]") // img with src ending .png
val masthead = doc.select("div.masthead").first() // div with class=masthead
val resultDivs = doc.select("h3.r > div") // direct div after h3
val resultAs = resultDivs.select("a") // A elements within resultDivs
8. 修改 HTML
- 设置属性值
// Elements 集合支持批量修改属性。例如,要向 div 内的每个 a 元素添加 rel="nofollow" 属性:
doc.select("div.comments a").attr("rel", "nofollow")
- 设置元素的 HTML 标签
val div = doc.select("div").first() // <div></div>
// 清除元素中所有现有的内部 HTML,并将其替换为已解析的 HTML。
div.html("<p>lorem ipsum</p>") // <div><p>lorem ipsum</p></div>
// 分别将 HTML 添加到元素内部 HTML 的开头或结尾
div.prepend("<p>First</p>")
div.append("<p>Last</p>") // now: <div><p>First</p><p>lorem ipsum</p><p>Last</p></div>
val span = doc.select("span").first() // <span>One</span>
// 将 HTML 包裹在元素的外部 HTML 周围。
span.wrap("<li><a href='https://itmob.cn/'></a></li>") // now: <li><a href="https://itmob.cn"><span>One</span></a></li>
- 设置元素的文本内容
val div = doc.select("div").first() // <div></div>
div.text("five > four") // <div>five > four</div>
div.prepend("First ")
div.append(" Last") // now: <div>First five > four Last</div>
关于 jsoup 的更多用法详见官方文档:Cookbook: recipes for using jsoup