目录

一.什么是jsoup

二.解析和遍历文档

三.从字符串解析文档

四.解析body部分

五.从URL加载文档

六.从文件加载文档

七.使用DOM方法浏览文档

八.使用选择器语法查找元素

九.从元素中提取属性,文本和HTML

十.将相对路径的URL解析为绝对URL

十一.设置属性值

十二.设置元素的HTML

十三. 设置元素的文本内容

十四.清理HTML


一.什么是jsoup

jsoup是一个用于实际处理HTML的Java库。它使用HTML最佳DOM方法和css选择器,为获取URL以及提取和处理数据提供了非常方便的API。

简单地说,他是一个Java爬虫给的api工具方法。

他的优点:

jsoup 实现WHATWG HTML5规范,并将HTML解析为与现代浏览器相同的DOM.

1.从URL,文件或字符串中抓取并解析HTML

2.使用DOM遍历或css选择器查找和提取数据

3.处理HTML元素,属性和文本

4.根据安全的白名单清除用户提交的内容,以防止XSS攻击

5.输出整洁的HTML

个人理解:jsoup是构建DOM树的方式,对树上的元素标签就行处理

二.解析和遍历文档

//1.测试  Jsoup.parse 的用法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创建干净的完整的dom树

未关闭的标签(例如<p>hello 解析为<p>hello</p>)

隐式标签  (例如,将裸体<td>table data</td> 包裹<table><tr><td>)

可靠得创建文档结构 (html包含head和body,并且头部中仅包含适当的元素)

文档的对象模型

文档由 Elements和TestNode组成

继承链 Document扩展Element延申Node。TextNode延申Node

一个元素包含一个子节点列表。并具有一个父元素,他们仅提供子元素的过滤列表

三.从字符串解析文档

问题:

你在java字符串中又HTML,并且想要解析该HTML以获得其内容,或者确保其格式正确,或者对其进行修改。该字符串可能来自用户输入,文件或者来自网络

解决方案:

使用静态的Jsoup.parse(String html)方法或者 Jsoup .parse(String html,String baseUri)如果网页来自网络,并且你想要获取绝对URL

String html = "<html><head><title>First parse</title></head>"+ "<body><p>Parsed HTML into a doc.</p></body></html>";Document doc = Jsoup.parse(html);

四.解析body部分

问题

你要解析正文的HTML片段(例如,div包含几个p标签;而不是完整的HTML文档)。可能是由用户提交或评论在CMS中编辑页面的正文提供的。

解决方案

Jsoup.parsebodyFragment(String html);

 String html="<div><p>Lorem ipsum.</p>";Document doc=Jsoup.parseBodyFragment(html);Element element =doc.body();

描述

该parseBodyFragment方法创建一个空的shell文档,并将已解析的HTML插入body元素中,如果使用常规Jsoup.parse(String html)方法,通常会得到相同的结果,但是将输入作为主体片段进行显示处理可确保将用户提供的所有HTML都解析为body元素

该Documnet.boy()方法检索文档body元素的子元素,相当于doc.getElementsByTag("body");

五.从URL加载文档

您需要从网上获取并解析HTML文档,并在其中查找数据

解决方案

使用Jsoup.connect(String URL);

Document doc3 = Jsoup.connect("http://www.baidu.com/").get();String title = doc3.title();Document doc4 = Jsoup.connect("http://www.baidu.com").data("query", "Java").userAgent("Mozilla").cookie("auth", "token").timeout(3000).post();String tile=doc4.title();

描述

该connect(String url) 方法创建一个new Connect,并get()获取解析一个HTML文件。如果提取网址时发生错误,就会报一个IOException,您将适当的处理它

该Connect接口旨在用于方法链接以构建特定的请求

六.从文件加载文档

问题

从磁盘中读取html文件,您想要加载和解析该文件,然后可以操纵或提取其中的数据

解决方案

使用静态 JSoup.parse(File in,String charsetName,String baseUri);

File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");

描述

parse(File in, String charsetName, String baseUri)方法加载并解析HTML文件。如果在加载文件时发生错误,它将抛出一个IOException,您应该适当地处理它。

   baseUri解析器使用该参数在<base href>找到元素之前解析文档中的相对URL 。如果您不担心此问题,可以改为传递一个空字符串。

有一种姐妹方法parse(File in, String charsetName),该方法使用文件的位置作为baseUri。如果您在本地文件系统站点上工作,并且指向该站点的相对链接也在文件系统上,则此功能很有用。

七.使用DOM方法浏览文档

问题

您有一个要从中提取数据的HTML文档。通常你知道HTML文档的结构

解决问题的思路

将HTML解析之后,使用DOM的方法Document

 5.使用Dom 方法浏览文档Document doc5 = Jsoup.connect("https://www.baidu.com/").get();Elements s_map =doc5.getElementsByTag("map");s_map.forEach((value)->{Elements hrefs=value.getElementsByTag("area");hrefs.forEach((href)->{try {String URL=href.getElementsByAttribute("href").get(0).attr("href");System.out.println("URL = " + URL);} catch (Exception e) {e.printStackTrace();}});});

描述

元素提供了一系列类似于DOM的方法来查找元素,以及调取和处理数据。DOM获取器是上下文的;在父文档需要调用的时候,他在文档下找到匹配的元素

在子元素上调用后,他们在该子元素下找到了元素,这样,您就可以在所需的数据上进行筛选

寻找元素

  • getElementById(String id)
  • getElementsByTag(String tag)
  • getElementsByClass(String className)
  • getElementsByAttribute(String key) (和相关方法)
  • 元素的兄弟姐妹:siblingElements()firstElementSibling()lastElementSibling()nextElementSibling()previousElementSibling()
  • 图:parent()children()child(int index)

元素数据

  • attr(String key)获取和attr(String key, String value)设置属性
  • attributes() 获取所有属性
  • id()className()classNames()
  • text()获取并text(String value)设置文本内容
  • html()获取并html(String value)设置内部HTML内容
  • outerHtml() 获得外部HTML值
  • data()获取数据内容(例如scriptstyle标签)
  • tag() 和 tagName()

处理HTML和文本

  • append(String html), prepend(String html)
  • appendText(String text), prependText(String text)
  • appendElement(String tagName), prependElement(String tagName)
  • html(String value)

八.使用选择器语法查找元素

问题

您想使用css或类似jquery的选择器语法查找或操作元素

解决方案

Element.select(String selector)和Elements.select(String selector)方法:

使用选择器语法查找元素
CSS或类似jquery的选择器语法查找或操作元素。使用Element.select(String selector)和Elements.select(String selector)方法: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#logo
el.class:具有类的元素,例如 div.masthead
el[attr]:具有属性的元素,例如 a[href]
任何组合,例如 a[href].highlight
ancestor child:源自祖先的子元素,例如,在“ body”类的块下的任何位置.body p找到p元素
parent > child:直接从父级派生的子元素,例如div.content > pfindp元素;并body > *找到身体标签的直接子代
siblingA + siblingB:查找紧随同级A的同级B元素,例如 div.head + div
siblingA ~ siblingX:查找同级X元素后跟同级A,例如 h1 ~ p
el, 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,依此类推。

九.从元素中提取属性,文本和HTML

问题

解析文档并找到一些元素以后你需要获取这些元素里的数据

解决方案

要获取属性的值,请使用Node.attr(String key)方法

对于元素(及其组合的子元素)上的文本,请使用Element.text();

对于使用Element.html(),或Node.outerHtml()酌情使用

例子:

//        要获取属性的值,请使用Node.attr(String key)方法
//        对于元素(及其组合的子元素)上的文本,请使用 Element.text()
//        对于HTML,请使用Element.html(),或Node.outerHtml()酌情使用
//
//        例子:String html = "<p>An <a href='http://example.com/'><b>example</b></a> link.</p>";Document document=Jsoup.parse(html);String  href=document.select("a[href]").attr("href");System.out.println("href = " + href);String text = document.body().text(); // "An example link"System.out.println("text = " + text);String ahref= document.select("a[href]").text();System.out.println("ahref = " + ahref);String outhtml=document.select("a").outerHtml();System.out.println("outhtml = " + outhtml);String htmlHref =document.select("a").html();System.out.println("htmlHref = " + htmlHref);

上面的方法是元素数据访问方法的核心。还有其他一些:

Element.id()
Element.tagName()
Element.className() 和 Element.hasClass(String className)
所有这些访问器方法都有相应的设置器方法来更改数据。

十.将相对路径的URL解析为绝对URL

解决方案

确保base URI在解析文档时指定一个(从URL加载时是隐式的)
使用abs:属性前缀可以从属性解析绝对URL:

Document doc = Jsoup.connect("http://jsoup.org").get();Element link = doc.select("a").first();
String relHref = link.attr("href"); // == "/"
String absHref = link.attr("abs:href"); // "http://jsoup.org/"

描述

在HTML元素中,通常是相对于文档的位置写URL <a href="/download">...</a>。当使用该Node.attr(String key)方法获取href属性时,将按源HTML中指定的方式返回该属性。

如果要获取绝对URL,则有一个属性键前缀abs:,该属性键前缀将导致该属性值根据文档的基本URI(原始位置)进行解析:attr("abs:href")

对于此用例,在解析文档时指定基本URI非常重要。

如果您不想使用abs:前缀,那么还有一种方法Node.absUrl(String key)可以执行相同的操作,但是可以通过自然属性键进行访问。

package org.jsoup.examples;import org.jsoup.Jsoup;
import org.jsoup.helper.Validate;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;import java.io.IOException;/*** Example program to list links from a URL.*/
public class ListLinks {public static void main(String[] args) throws IOException {Validate.isTrue(args.length == 1, "usage: supply url to fetch");String url = args[0];print("Fetching %s...", url);Document doc = Jsoup.connect(url).get();Elements links = doc.select("a[href]");Elements media = doc.select("[src]");Elements imports = doc.select("link[href]");print("\nMedia: (%d)", media.size());for (Element src : media) {if (src.normalName().equals("img"))print(" * %s: <%s> %sx%s (%s)",src.tagName(), src.attr("abs:src"), src.attr("width"), src.attr("height"),trim(src.attr("alt"), 20));elseprint(" * %s: <%s>", src.tagName(), src.attr("abs:src"));}print("\nImports: (%d)", imports.size());for (Element link : imports) {print(" * %s <%s> (%s)", link.tagName(),link.attr("abs:href"), link.attr("rel"));}print("\nLinks: (%d)", links.size());for (Element link : links) {print(" * a: <%s>  (%s)", link.attr("abs:href"), trim(link.text(), 35));}}private static void print(String msg, Object... args) {System.out.println(String.format(msg, args));}private static String trim(String s, int width) {if (s.length() > width)return s.substring(0, width-1) + ".";elsereturn s;}
}

十一.设置属性值

问题

您有一个解析后的文档,在将其保存到磁盘或作为HTTP响应发送之前,您想更新属性值。

解决方案

使用属性设置器方法Element.attr(String key, String value)和Elements.attr(String key, String value)。

如果需要修改class元素的属性,请使用Element.addClass(String className)和Element.removeClass(String className)方法。

该Elements集合具有批量属性和类方法。例如,要将rel="nofollow"属性添加到adiv中的每个元素:

doc.select("div.comments a").attr("rel", "nofollow");

描述

像中的其他方法一样Element,这些attr方法返回当前值Element(或Elements在处理来自select的集合时)。这允许方便的方法链接:

doc.select("div.masthead").attr("title", "jsoup").addClass("round-box");

十二.设置元素的HTML

问题

修改元素的HTML。

解决方案

Element div = doc.select("div").first(); // <div></div>
div.html("<p>lorem ipsum</p>"); // <div><p>lorem ipsum</p></div>
div.prepend("<p>First</p>");
div.append("<p>Last</p>");
// now: <div><p>First</p><p>lorem ipsum</p><p>Last</p></div>Element span = doc.select("span").first(); // <span>One</span>
span.wrap("<li><a href='http://example.com/'></a></li>");
// now: <li><a href="http://example.com"><span>One</span></a></li>

讨论区

Element.html(String html) 清除元素中所有现有的内部HTML,并将其替换为已解析的HTML。
Element.prepend(String first)和Element.append(String last)分别添加HTML到元素的内部HTML的开始或结束,
Element.wrap(String around)将HTML包装在元素的外部HTML周围。
您还可以使用Element.prependElement(String tag)和Element.appendElement(String tag)方法创建新元素,并将它们作为子元素插入到文档流中。

十三. 设置元素的文本内容

问题

修改HTML文档的文本内容。

解决方案

使用以下文本设置器方法Element:

Element div = doc.select("div").first(); // <div></div>
div.text("five > four"); // <div>five &gt; four</div>
div.prepend("First ");
div.append(" Last");
// now: <div>First five &gt; four Last</div>

讨论区

文本设置器方法反映了HTML设置器方法:

Element.text(String text) 清除元素中所有现有的内部HTML,并将其替换为提供的文本。
Element.prepend(String first)和Element.append(String last)添加文本节点到开始或一个元素的内部HTML的结束
文本应以未编码的形式提供:<,>等字符将被视为文字,而不是HTML。

十四.清理HTML

问题

您要允许不受信任的用户提供HTML以在您的网站上输出(例如,作为评论提交)。您需要清除此HTML,以避免跨站点脚本(XSS)攻击。

解决方案

将jsoup HTMLCleaner用于由指定的配置Whitelist。

String unsafe = "<p><a href='http://example.com/' onclick='stealCookies()'>Link</a></p>";
String safe = Jsoup.clean(unsafe, Whitelist.basic());
// now: <p><a href="http://example.com/" rel="nofollow">Link</a></p>

讨论区

针对您的网站的跨站点脚本攻击可能真的毁了您的一天,更不用说用户了。许多站点通过不允许用户提交的内容中包含HTML来避免XSS攻击:它们仅强制执行纯文本,或使用替代标记语法(如Wiki-text或Markdown)。这些对用户来说很少是最佳解决方案,因为它们降低了表达能力,并迫使用户学习新语法。

更好的解决方案可能是使用富文本格式的所见即所得编辑器(例如CKEditor或TinyMCE)。这些输出HTML,并允许用户进行可视化工作。但是,它们的验证是在客户端完成的:您需要应用服务器端的验证来清理输入并确保HTML可以安全地放置在您的站点上。否则,攻击者可以避免客户端Java脚本验证并将不安全的HMTL直接注入您的站点中

jsoup白名单清理程序的工作原理是:解析输入的HTML(在安全的沙盒环境中),然后遍历解析树,仅允许将已知安全的标记和属性(和值)传递到清除的输出中。

它不使用正则表达式,这不适用于此任务。

jsoup提供了一系列Whitelist配置以满足大多数需求;如有必要,可以对其进行修改,但要小心。

清理程序不仅对避免XSS有用,而且在限制用户可以提供的元素范围方面也很有用:您可能会同意text a,strong元素,但对结构div或table元素不是很满意。

jsoup学习笔记简明教程相关推荐

  1. 108页《SpringBoot 学习笔记完整教程》PDF附下载

    今天Hydra分享给大家一本108页的<SpringBoot 学习笔记完整教程>,从SpringBoot的基本入门使用,到搭建项目进行代码实战,最终研究底层实现原理,基本涵盖了各个环节,可 ...

  2. Fiddler 学习笔记--Fiddler 教程

    学习网址: 1.https://www.cnblogs.com/yyhh/p/5140852.html 2.https://www.cnblogs.com/FounderBox/p/4653588.h ...

  3. 基于weblogic 的EJB 学习笔记-JSP教程,资料/其它

    http://www.west263.com/www/info/14655-1.htm ejb 学习笔记 1.ejb 基础知识 (1) 无状态会话bean     不保存客户机的会话状态     优点 ...

  4. C#学习笔记——菜鸟教程C#学习重点归纳

    C#学习笔记 第一章:程序结构 一.结构 命名空间声明(Namespace declaration) 一个 class Class 方法 Class 属性 一个 Main 方法 语句(Statemen ...

  5. Hadoop学习笔记——入门教程(虚拟机安装LinuxHadoop环境搭建配置)

    文章目录 一.Hadoop安装配置文档及注意事项 二.Hadoop概述 2.1.Hadoop是什么 2.2.Hadoop的发展历史 2.3.Hadoop三大发行版本 2.3.1 Apache Hado ...

  6. git学习笔记兼教程

    前言 我先是看廖老师的git教程学习的git,小伙伴们可以直接百度廖老师的教程. 这里自己总结一下,可以当作教程,也供自己查阅使用. 1.安装 linux下安装十分方便,直接sudo apt-get ...

  7. Linux学习笔记---Vim教程

    Window10-Linux子系统-Vim编辑器教程 1. (1)vim 文件 -进入vim编辑器 (2)按"a"或"i"-进行编辑 (3)按Esc-退出保存( ...

  8. Android NDK开发入门学习笔记(图文教程,极其详尽)

    以前也简单用过JNI,但是只是简单用一下,好多都不明白.最近在看源码部分,有涉及到JNI调用的,所以这次打算彻底把它搞定. 先普及一下JNI的调用关系:JAVA-------------------- ...

  9. docker 学习笔记一(教程) 快速上手

    之前在做机器学习开发的时候往往会采用virtual env 和 conda等环境管理工具,为了让开发和部署及环境的搭建更加方便,同时也方便在云上搭建开发及部署环境,打算使用docker提高开发效率,故 ...

最新文章

  1. 英特尔史上最大收购!英特尔拟300亿美元收购GF,审批成关键!
  2. Python 程序扩展名(py, pyc, pyw, pyo, pyd) 及发布程序时的选择
  3. 【转】 UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合
  4. 【Linux】XXX is not in the sudoers file …… 的解决方案
  5. 多线程和socket练习
  6. 怎样在 SSASserver之间做同步
  7. matlab 对称矩阵特征值为负数,MATLAB中对称矩阵的复特征向量
  8. IPV6 阿里DDNS
  9. 如何美化CheckBox
  10. pngimg 可以商用吗_免费商用无版权素材 免费图库 抠图 PNG 插画素材
  11. 用 JAVA 开发游戏连连看
  12. SAP那些事-理论篇-13-SAP问题解决思路
  13. 拦截电话--- 关于利用反射 调用系统 hiden的 方法
  14. timing lib时序弧
  15. 大话数据结构系列之链队列结构(十二)
  16. import pyrender找不到指定模块
  17. 使用IDEA完成一个SpringBoot的demo
  18. 16位字长的计算机,十六位字长的计算机是指计算机16位十进制数的计算机吗
  19. cognos java_Cognos第三方用户认证(CustomJavaProvider)
  20. 解决VScode中文乱码问题

热门文章

  1. 遵循gpl协议 采用jar包_采用GPL协议的程序,可以免费应用于商业用途吗?
  2. SAP 货源清单Source list
  3. uni-app获取视频缩略图封面插件
  4. SQLServer恢复表级数据
  5. 苹果连接计算机无法识别usb设备,苹果iTunes和同步助手都无法识别USB设备怎么办...
  6. [Houdini]Tops初识
  7. 诺基亚N81手机密码如何解锁
  8. java3d 实例_java 3D画图实例
  9. 两种启动tomcat的方法
  10. 着色器(Shader)之顶点着色器