java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > jsoup的使用

什么是jsoup及jsoup的使用

作者:ThinkStu

jsoup是一款基于Java的HTML解析器,它提供了一套非常省力的API,不但能直接解析某个URL地址、HTML文本内容,而且还能通过类似于DOM、CSS或者jQuery的方法来操作数据,所以 jsoup 也可以被当做爬虫工具使用,这篇文章主要介绍了什么是jsoup及jsoup的使用,需要的朋友可以参考下

本文在写作过程中参考了官方文档,传送门

一、jsoup概述

  jsoup 是一款基于 Java 的HTML解析器,它提供了一套非常省力的API,不但能直接解析某个URL地址、HTML文本内容,而且还能通过类似于DOM、CSS或者jQuery的方法来操作数据,所以 jsoup 也可以被当做爬虫工具使用。

二、相关概念简介

三、获取文档(Document)

获得文档对象 Document 一共有4种方法,分别对应不同的获取方式。

正式开始之前,我们需要导入有关 jar 包。

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.15.1</version>
</dependency>

3.1)从URL中加载文档对象(常用)

使用 Jsoup.connect(String url).get()方法获取(只支持 http 和 https 协议):

Document doc = Jsoup.connect("http://csdn.com/").get();
String title = doc.title();
System.out.println(title);

connect(String url)方法创建一个新的 Connection并通过.get()或者.post()方法获得数据。如果从该URL获取HTML时发生错误,便会抛出 IOException,应适当处理。

Connection 接口还提供一个方法链来解决特殊请求,我们可以在发送请求时带上请求的头部参数,具体如下:

Document doc = Jsoup.connect("http://csdn.com")
  .data("query", "Java")
  .userAgent("Mozilla")
  .cookie("auth", "token")
  .timeout(8000)
  .post();
  System.out.println(doc);

想获得完整的响应对象和响应码?我们可以使用execute()方法:

// 获得响应对象
Connection.Response response = Jsoup.connect("http://csdn.com").execute();
int                 code     = response.statusCode();
// 输出状态码:200
System.out.println(code);

3.2)从本地文件中加载文档对象

可以使用静态的Jsoup.parse(File in, String charsetName) 方法从文件中加载文档。其中in表示路径,charsetName表示编码方式,示例代码:

File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8");
System.out.println(doc);

3.3)从字符串文本中加载文档对象

使用静态的Jsoup.parse(String html) 方法可以从字符串文本中获得文档对象 Document ,示例代码:

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

3.4)从<body>片断中获取文档对象

使用Jsoup.parseBodyFragment(String html)方法.

String html = "<p>Lorem ipsum.</p>";
Document doc = Jsoup.parseBodyFragment(html);
// doc 此时为:<body> <p>Lorem ipsum.</p></body>
Element body = doc.body();
System.out.println(body);

parseBodyFragment 方法创建一个新的文档,并插入解析过的HTML到body元素中。假如你使用正常的 Jsoup.parse(String html) 方法,通常也能得到相同的结果,但是明确将用户输入作为 body 片段处理是个更好的方式。

Document.body() 方法能够取得文档body元素的所有子元素,与 doc.getElementsByTag("body")相同。

四、选择元素(Element)

解析文档对象并获取数据一共有 2 种方式,分别为 DOM方式、CSS选择器方式,我们可以选择一种自己喜欢的方式去获取数据,效果一样。

4.1)DOM方式

将HTML解析成一个Document之后,就可以使用类似于DOM的方法进行操作。

// 获取csdn首页所有的链接
Document doc       = Jsoup.connect("http://csdn.com").get();
Elements elements  = doc.getElementsByTag("body");
Elements contents  = elements.first().getElementsByTag("a");
for (Element content : contents) {
    String linkHref = content.attr("href");
    String linkText = content.text();
    System.out.print(linkText+"\t");
    System.out.println(linkHref);
}

说明

Elements这个对象提供了一系列类似于DOM的方法来查找元素,抽取并处理其中的数据。具体如下:

4.1.1)查找元素

4.1.2)获取元素数据

4.1.3)操作HTML文本

append(String html):在末尾追加HTML文本prepend(String html):在开头追加HTML文本html(String value):在匹配元素内部添加HTML文本。

4.2)CSS选择器方式

可以使用类似于CSS选择器的语法来查找和操作元素,常用的方法为select(String selector)

Document doc = Jsoup.connect("http://csdn.com").get();
// 获取带有 href 属性的 a 元素
Elements elements = doc.select("a[href]");
for (Element content : elements) {
    String linkHref = content.attr("href");
    String linkText = content.text();
    System.out.print(linkText + "\t");
    System.out.println(linkHref);
}

4.2.1)说明

select()方法在DocumentElementElements对象中都可以使用,而且是上下文相关的,因此可实现指定元素的过滤,或者采用链式访问。

select() 方法将返回一个Elements集合,并提供一组方法来抽取和处理结果。

4.2.2)select(String selector)方法参数简介

4.2.3)参数属性组合使用

4.2.4)特殊参数:伪选择器

五、获取数据(Node)

在获得文档对象并且指定查找元素后,我们就可以获取元素中的数据。
这些访问器方法都有相应的setter方法来更改数据。

String   html = "<p><a href='http://csdn.com/'><b>example</b></a> link.</p>";
Document doc  = Jsoup.parse(html);
// 查找第一个<a>元素
Element link = doc.select("a").first();
// 输出:example
String text     = link.text();
// 输出:http://csdn.com/
String href = link.attr("href");
// 输出:<b>example</b>
String aHtml     = link.outerHtml();
// 输出:<a href='http://csdn.com/'><b>example</b></a>
String aOuterHtml     = link.outerHtml();

六、修改数据

在解析了一个Document对象之后,你可能想修改其中的某些属性值,并把它输出到前台页面或保存到其他地方,jsoup对此提供了一套非常简便的接口(支持链式写法)。

6.1)设置属性的值

当以下方法针对Element对象操作时,只有一个元素会受到影响。当针对Elements对象进行操作时,可能会影响到多个元素。

Document doc = Jsoup.connect("http://csdn.com").get();
// 复数,Elements
Elements elements = doc.getElementsByClass("text");
// 单数,Element
Element element = elements.first();
// 复数对象,所有 class="text" 的元素都将受到影响
elements.attr("name","goods");
// 单数对象,只有一个元素会受到影响(链式写法)
element.attr("name","shop")
        .addClass("red");

6.2)修改元素的HTML内容

可以使用Element中的HTML设置方法具体如下:

Document doc = Jsoup.connect("http://csdn.com").get();
Element div = doc.select("div").first();
div.html("<p>csdn</p>");
div.prepend("<p>a</p>");
div.append("<p>good</p>");
// 输出:<div"> <p>a</p> <p>csdn</p> <p>good</p> </div>
Element span = doc.select("span").first();
span.wrap("<li><a href='...'></a></li>");
// 输出: <li><a href="..." rel="external nofollow" > <span>csdn</span> </a></li>

6.3)修改元素的文本内容

对于传入的文本,如果含有像 <, > 等这样的字符,将以文本处理,而非HTML。

 // <div></div>
Element div = doc.select("div").first();
div.text(" one "); 
div.prepend(" two ");
div.append(" three ");
// 输出: <div> two one three </div>

七、其他功能

7.1)相对路径转绝对路径

问题描述
  你有一个包含相对URLs路径的HTML文档,现在需要将这些相对路径转换成绝对路径的URLs。

解决方式

Document doc = Jsoup.connect("http://www.open-open.com").get();
Element link = doc.select("a").first();
// 输出:/
String relHref = link.attr("href");
// 输出:http://www.open-open.com/
String absHref = link.attr("abs:href");

说明

在HTML元素中,URLs经常写成相对于文档位置的相对路径,如:<a href="/download">...</a>。当你使用 .attr(String key) 方法来取得a元素的href属性时,它将直接返回在HTML源码中指定的值。

假如你需要取得一个绝对路径,需要在属性名前加 abs: 前缀,这样就可以返回包含根路径的URL地址attr("abs:href")。因此在解析HTML文档时,定义base URI非常重要。

如果你不想使用abs: 前缀,还有一个方法能够实现同样的功能 .absUrl(String key)

7.2)消除不受信任的HTML (防止XSS攻击)

问题描述

  在某些网站中经常会提供用户评论的功能,但是有些不怀好意的用户,会搞一些脚本到评论内容中,而这些脚本可能会破坏整个页面的行为,更严重的是获取一些机要信息,此时需要清理该HTML,以避免跨站脚本攻击(XSS)。

解决方式
  使用clean()方法清除恶意代码,但需要指定一个配置的 Safelist(旧版本中是Whitelist),通常使用Safelist.basic()即可。Safelist的工作原理是将输入的 HTML 内容单独隔离解析,然后遍历解析树,只允许已知的安全标签和属性输出。

String unsafe = 
        "<p><a href='http://csdn.com/' οnclick='attack()'>Link</a></p>";
// 输出: <p><a href="http://csdn.com/" rel="external nofollow"  rel="external nofollow"  >Link</a></p>
String safe = Jsoup.clean(unsafe, Safelist.basic());
System.out.println(safe);

说明

  jsoup的Safelist不仅能够在服务器端对用户输入的HTML进行过滤,只输出一些安全的标签和属性,还可以限制用户可以输入的标签范围。 6.2)消除不受信任的HTML (防止XSS攻击)

问题描述

  在某些网站中经常会提供用户评论的功能,但是有些不怀好意的用户,会搞一些脚本到评论内容中,而这些脚本可能会破坏整个页面的行为,更严重的是获取一些机要信息,此时需要清理该HTML,以避免跨站脚本攻击(XSS)。

解决方式
  使用clean()方法清除恶意代码,但需要指定一个配置的 Safelist(旧版本中是Whitelist),通常使用Safelist.basic()即可。Safelist的工作原理是将输入的 HTML 内容单独隔离解析,然后遍历解析树,只允许已知的安全标签和属性输出。

String unsafe = 
        "<p><a href='http://csdn.com/' οnclick='attack()'>Link</a></p>";
// 输出: <p><a href="http://csdn.com/" rel="external nofollow"  rel="external nofollow"  >Link</a></p>
String safe = Jsoup.clean(unsafe, Safelist.basic());
System.out.println(safe);

说明

  jsoup的Safelist不仅能够在服务器端对用户输入的HTML进行过滤,只输出一些安全的标签和属性,还可以限制用户可以输入的标签范围。

7.3)jsoup使用代理

Connection.Response execute = Jsoup.connect("http://csdn.net/")
					               .proxy("12.12.12.12", 1080)	// 使用代理
					               .execute();

到此这篇关于什么是jsoup及jsoup的使用的文章就介绍到这了,更多相关jsoup的使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文