Jsoup
基于java平台的HTML解析工具,针对HTML字符串,URL地址。
功能
1. URL基于网络解析HTML
2. HTML字符串解析
3. 类DOM或CSS选择器解析
4. 解析Body片段
字符串、文件、网络解析、DOM树解析、选择器解析:
package util
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import org.jsoup.select.Elements
import java.io.File
//字符串解析
fun loadFromString() {
val stringURL:String = "<html><head><title>just for an example</title></head>" +
"<body>Hello World</body></html>"
val doc = Jsoup.parse(stringURL)
println("字符串解析")
println(doc.title())
println(doc.body())
println("---------------")
}
//html文件解析
fun loadFromFile(){
val file:File = File("D:/hello.htm")
val doc:Document = Jsoup.parse(file,"utf-8")
println("HTML文件解析")
println(doc.title())
println(doc.body())
println("----------------")
}
//网络获取解析(自动创建Connection取得HTML,出错抛出IO异常)
fun loadFromNet(){
val doc:Document = Jsoup.connect("http://www.baidu.com").get()
println("网络获取解析")
println(doc.title())
println("-----------------")
// //特殊需求样例
// val doc2:Document = Jsoup.connect("http://www.baidu.com")
// .data("query","info") // 请求参数
// .userAgent("I ’ m jsoup") // 设置 User-Agent
// .cookie("auth", "token")// 设置 cookie
// .timeout(3000) // 设置连接超时时间
// .post() // 使用 POST 方法访问 URL
}
//DOM树解析(与dom解析方法名相同,功能也相同)
fun loadByDOM(){
val file:File = File("D:/hello.htm")
val doc:Document = Jsoup.parse(file,"utf-8")
val element: Element = doc.getElementById("test")
val ele = doc.getElementsByTag("body")
println("DOM树解析")
println(element)
println(ele)
println("------------------")
}
//Body片段解析(创建空白文档插入解析的数据,形成新body片段)
fun loadFromBody(){
val stringURL:String = "<div>div style</div>"
val doc:Document = Jsoup.parseBodyFragment(stringURL)
val body = doc.body()
println("Body片段解析")
println(body)
println("-----------------------")
}
//选择器解析
fun loadFromSelector(){
val file:File = File("D:/hello.htm")
val doc:Document = Jsoup.parse(file,"utf-8")
val element: Elements = doc.select("a[href]")//附带href的a元素
println("选择器解析")
println(element)
println("------------------")
}
fun main(args: Array<String>) {
loadFromString()
loadFromFile()
loadFromNet()
loadByDOM()
loadFromBody()
loadFromSelector()
}
运行结果:
字符串解析
just for an example
<body>
Hello World
</body>
---------------
HTML文件解析
我是标题
<body>
<a id="test"></a>hello
<a href="http://www.baidu.com">School</a>
</body>
----------------
网络获取解析
百度一下,你就知道
-----------------
DOM树解析
<a id="test"></a>
<body>
<a id="test"></a>hello
<a href="http://www.baidu.com">School</a>
</body>
------------------
Body片段解析
<body>
<div>
div style
</div>
</body>
-----------------------
选择器解析
<a href="http://www.baidu.com">School</a>
------------------
Process finished with exit code 0
相对路径处理
有些htm采用相对路径来标示,因此我们需要获取到真正的数据就需要爬取他的绝对地址,相对路径类似于快捷方式,绝对路径是完整地址。比如example,这是相对路径,我们获取到是无法访问具体数据的。缺少前缀网址。
fun findAbsAddress(){
val doc = Jsoup.connect("http://www.baidu.com").get()
val element = doc.select("a").first()
val relHref = element.attr("href") //相对地址
val absHref = element.attr("abs:href") //绝对地址
println(absHref) //结果为:https://www.baidu.com/
}
保存前编辑
在你保存document中某项属性的时候,如果需要自定义一些必要的值,jsoup也是可以帮你处理掉的。
//自定义修改、添加内容
fun alterAttr(){
//源文件解析
val file:File = File("D:/hello.htm")
var doc:Document = Jsoup.parse(file,"utf-8")
//新增操作,为每个查找到的a标签,增加属性为name值为test
doc.select("a").attr("name","test")
//修改操作
doc.select("a").first()//修改第一个元素,如要全部替换需要遍历Elements操作
.text("替换后的内容")
.prepend("前缀追加--")
.append("--后缀追加")
//输出到其他文件便于观察
var fileWriter:FileWriter = FileWriter("D://hello2.htm")
fileWriter.write(doc.toString())
fileWriter.close()
}
修改前:
<html>
<head><title>just for an example</title>
</head>
<body>
<a id="test"></a>
<a href="www.baidu.com"></a>
</body>
</html>
修改后:
<html>
<head>
<title>just for an example</title>
</head>
<body>
<a id="test" name="test">前缀追加--替换后的内容--后缀追加</a>
<a href="www.baidu.com" name="test"></a>
</body>
</html>
安全防护机制
XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意攻击用户的特殊目的。XSS属于被动式的攻击,因为其被动且不好利用,所以许多人常忽略其危害性。所以我们经常只让用户输入纯文本的内容,但这样用户体验就比较差了。
使用jsoup HTML Cleaner 方法进行清除,但需要指定一个可配置的 Whitelist。
fun cleanWebSite(){
var unSafeWebSite:String = "<p><a href='http://example.com/' onclick='stealCookies()'>Link</a></p>"
var safeWebSite:String = Jsoup.clean(unSafeWebSite,Whitelist.basic())
println(safeWebSite)
}
结果:
<p><a href="http://example.com/" rel="nofollow">Link</a></p>
这样就避免你不知情的情况下,误点而造成一系列损失。
jsoup的whitelist清理器能够在服务器端对用户输入的HTML进行过滤,只输出一些安全的标签和属性。
jsoup提供了一系列的Whitelist基本配置,能够满足大多数要求;但如有必要,也可以进行修改,不过要小心。
这个cleaner非常好用不仅可以避免XSS攻击,还可以限制用户可以输入的标签范围。
参考jsoup官方文档。