💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# JSoup 教程 原文:http://zetcode.com/java/jsoup/ JSoup 教程是 JSoup HTML 解析器的入门指南。 在本教程中,我们将解析 HTML 字符串,本地 HTML 文件和网页中的 HTML 数据。 我们将清理数据并执行 Google 搜索。 ## JSoup JSoup 是用于提取和处理 HTML 数据的 Java 库。 它实现了 HTML5 规范,并将 HTML 解析为与现代浏览器相同的 DOM。 该项目的网站是 [jsoup.org](https://jsoup.org) 。 ## JSoup 功能 使用 JSoup,我们能够: * 从 URL,文件或字符串中抓取并解析 HTML * 使用 DOM 遍历或 CSS 选择器查找和提取数据 * 处理 HTML 元素,属性和文本 * 根据安全的白名单清除用户提交的内容,以防止 XSS 攻击 * 输出整洁的 HTML ## JSoup Maven 依赖项 在本教程的示例中,我们使用以下 Maven 依赖关系。 ```java <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.12.1</version> </dependency> ``` ## `JSoup`类 `JSoup`类通过其静态方法为 jsoup 函数提供了核心公共访问点。 例如,`clean()`方法清理 HTML 代码,`connect()`方法创建与 URL 的连接,或者`parse()`方法解析 HTML 内容。 ## JSoup 解析 HTML 字符串 在第一个示例中,我们将解析一个 HTML 字符串。 `com/zetcode/JSoupFromStringEx.java` ```java package com.zetcode; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; public class JSoupFromStringEx { public static void main(String[] args) { String htmlString = "<html><head><title>My title</title></head>" + "<body>Body content</body></html>"; Document doc = Jsoup.parse(htmlString); String title = doc.title(); String body = doc.body().text(); System.out.printf("Title: %s%n", title); System.out.printf("Body: %s", body); } } ``` 该示例分析 HTML 字符串并输出其标题和正文内容。 ```java String htmlString = "<html><head><title>My title</title></head>" + "<body>Body content</body></html>"; ``` 此字符串包含简单的 HTML 数据。 ```java Document doc = Jsoup.parse(htmlString); ``` 使用`Jsoup`的`parse()`方法,我们解析 HTML 字符串。 该方法返回一个 HTML 文档。 ```java String title = doc.title(); ``` 文档的`title()`方法获取文档的`title`元素的字符串内容。 ```java String body = doc.body().text(); ``` 文档的`body()`方法返回`body`元素; 其`text()`方法获取元素的文本。 ## JSoup 解析本地 HTML 文件 在第二个示例中,我们将解析本地 HTML 文件。 我们使用重载的`Jsoup.parse()`方法,该方法将`File`对象作为其第一个参数。 `index.html` ```java <!DOCTYPE html> <html> <head> <title>My title</title> <meta charset="UTF-8"> </head> <body> <div id="mydiv">Contents of a div element</div> </body> </html> ``` 对于示例,我们使用上面的 HTML 文件。 `com/zetcode/JSoupFromFileEx.java` ```java package com.zetcode; import java.io.File; import java.io.IOException; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; public class JSoupFromFileEx { public static void main(String[] args) throws IOException { String fileName = "src/main/resources/index.html"; Document doc = Jsoup.parse(new File(fileName), "utf-8"); Element divTag = doc.getElementById("mydiv"); System.out.println(divTag.text()); } } ``` 该示例将分析`src/main/resources/`目录中的`index.html`文件。 ```java Document doc = Jsoup.parse(new File(fileName), "utf-8"); ``` 我们使用`Jsoup.parse()`方法解析 HTML 文件。 ```java Element divTag = doc.getElementById("mydiv"); ``` 使用文档的`getElementById()`方法,我们通过元素的 ID 获得元素。 ```java System.out.println(divTag.text()); ``` 使用元素的`text()`方法检索标签的文本。 ## JSoup 读取网站的标题 在以下示例中,我们将抓取并解析网页,然后检索`title`元素的内容。 `com/zetcode/JSoupTitleEx.java` ```java package com.zetcode; import java.io.IOException; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; public class JSoupTitleEx { public static void main(String[] args) throws IOException { String url = "http://webcode.me"; Document doc = Jsoup.connect(url).get(); String title = doc.title(); System.out.println(title); } } ``` 在代码示例中,我们读取了指定网页的标题。 ```java Document doc = Jsoup.connect(url).get(); ``` Jsoup 的`connect()`方法创建到给定 URL 的连接。 `get()`方法执行 GET 请求并解析结果; 它返回一个 HTML 文档。 ```java String title = doc.title(); ``` 使用文档的`title()`方法,我们获得 HTML 文档的标题。 ## JSoup 读取 HTML 源码 下一个示例检索网页的 HTML 源。 `com/zetcode/JSoupHTMLSourceEx.java` ```java package com.zetcode; import java.io.IOException; import org.jsoup.Jsoup; public class JSoupHTMLSourceEx { public static void main(String[] args) throws IOException { String webPage = "http://webcode.me"; String html = Jsoup.connect(webPage).get().html(); System.out.println(html); } } ``` 该示例打印网页的 HTML。 ```java String html = Jsoup.connect(webPage).get().html(); ``` `html()`方法返回元素的 HTML; 在我们的案例中,整个文档的 HTML 源代码。 ## JSoup 获取信息 HTML 文档的元信息提供有关网页的结构化元数据,例如其描述和关键字。 `com/zetcode/JSoupMetaInfoEx.java` ```java package com.zetcode; import java.io.IOException; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; public class JSoupMetaInfoEx { public static void main(String[] args) throws IOException { String url = "http://www.jsoup.org"; Document document = Jsoup.connect(url).get(); String description = document.select("meta[name=description]").first().attr("content"); System.out.println("Description : " + description); String keywords = document.select("meta[name=keywords]").first().attr("content"); System.out.println("Keywords : " + keywords); } } ``` 该代码示例检索有关指定网页的元信息。 ```java String keywords = document.select("meta[name=keywords]").first().attr("content"); ``` 文档的`select()`方法查找与给定查询匹配的元素。 `first()`方法返回第一个匹配的元素。 使用`attr()`方法,我们获得`content`属性的值。 ## JSoup 解析链接 下一个示例分析 HTML 页面中的链接。 `com/zetcode/JSoupLinksEx.java` ```java package com.zetcode; import java.io.IOException; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; public class JSoupLinksEx { public static void main(String[] args) throws IOException { String url = "http://jsoup.org"; Document document = Jsoup.connect(url).get(); Elements links = document.select("a[href]"); for (Element link : links) { System.out.println("link : " + link.attr("href")); System.out.println("text : " + link.text()); } } } ``` 在该示例中,我们连接到网页并解析其所有链接元素。 ```java Elements links = document.select("a[href]"); ``` 要获取链表,我们使用文档的`select()`方法。 ## JSoup 清理 HTML 数据 Jsoup 提供了用于清理 HTML 数据的方法。 `com/zetcode/JSoupSanitizeEx.java` ```java package com.zetcode; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.safety.Cleaner; import org.jsoup.safety.Whitelist; public class JSoupSanitizeEx { public static void main(String[] args) { String htmlString = "<html><head><title>My title</title></head>" + "<body><center>Body content</center></body></html>"; boolean valid = Jsoup.isValid(htmlString, Whitelist.basic()); if (valid) { System.out.println("The document is valid"); } else { System.out.println("The document is not valid."); System.out.println("Cleaned document"); Document dirtyDoc = Jsoup.parse(htmlString); Document cleanDoc = new Cleaner(Whitelist.basic()).clean(dirtyDoc); System.out.println(cleanDoc.html()); } } } ``` 在示例中,我们清理并清理 HTML 数据。 ```java String htmlString = "<html><head><title>My title</title></head>" + "<body><center>Body content</center></body></html>"; ``` HTML 字符串包含不推荐使用的`center`元素。 ```java boolean valid = Jsoup.isValid(htmlString, Whitelist.basic()); ``` `isValid()`方法确定字符串是否为有效的 HTML。 白名单是可以通过清除程序的 HTML(元素和属性)列表。 `Whitelist.basic()`定义了一组基本的干净 HTML 标记。 ```java Document dirtyDoc = Jsoup.parse(htmlString); Document cleanDoc = new Cleaner(Whitelist.basic()).clean(dirtyDoc); ``` 借助`Cleaner`,我们清理了脏的 HTML 文档。 ```java The document is not valid. Cleaned document <html> <head></head> <body> Body content </body> </html> ``` 这是程序的输出。 我们可以看到中心元素已被删除。 ## JSoup 执行 Google 搜索 以下示例使用 Jsoup 执行 Google 搜索。 `com/zetcode/JsoupGoogleSearchEx.java` ```java package com.zetcode; import java.io.IOException; import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; public class JsoupGoogleSearchEx { private static Matcher matcher; private static final String DOMAIN_NAME_PATTERN = "([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,15}"; private static Pattern patrn = Pattern.compile(DOMAIN_NAME_PATTERN); public static String getDomainName(String url) { String domainName = ""; matcher = patrn.matcher(url); if (matcher.find()) { domainName = matcher.group(0).toLowerCase().trim(); } return domainName; } public static void main(String[] args) throws IOException { String query = "Milky Way"; String url = "https://www.google.com/search?q=" + query + "&num=10"; Document doc = Jsoup .connect(url) .userAgent("Jsoup client") .timeout(5000).get(); Elements links = doc.select("a[href]"); Set<String> result = new HashSet<>(); for (Element link : links) { String attr1 = link.attr("href"); String attr2 = link.attr("class"); if (!attr2.startsWith("_Zkb") && attr1.startsWith("/url?q=")) { result.add(getDomainName(attr1)); } } for (String el : result) { System.out.println(el); } } } ``` 该示例为`"Milky Way"`一词创建搜索请求。 它会打印十个与该术语匹配的域名。 ```java private static final String DOMAIN_NAME_PATTERN = "([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,15}"; private static Pattern patrn = Pattern.compile(DOMAIN_NAME_PATTERN); ``` Google 搜索返回长链接,我们要从中获取域名。 为此,我们使用正则表达式模式。 ```java public static String getDomainName(String url) { String domainName = ""; matcher = patrn.matcher(url); if (matcher.find()) { domainName = matcher.group(0).toLowerCase().trim(); } return domainName; } ``` `getDomainName()`使用正则表达式匹配器从搜索链接返回域名。 ```java String query = "Milky Way"; ``` 这是我们的搜索词。 ```java String url = "https://www.google.com/search?q=" + query + "&num=10"; ``` 这是执行 Google 搜索的网址。 ```java Document doc = Jsoup .connect(url) .userAgent("Jsoup client") .timeout(5000).get(); ``` 我们连接到 URL,设置 5s 超时,然后发送 GET 请求。 返回 HTML 文档。 ```java Elements links = doc.select("a[href]"); ``` 从文档中,我们选择链接。 ```java Set<String> result = new HashSet<>(); for (Element link : links) { String attr1 = link.attr("href"); String attr2 = link.attr("class"); if (!attr2.startsWith("_Zkb") && attr1.startsWith("/url?q=")) { result.add(getDomainName(attr1)); } } ``` 我们寻找不具有`class="_Zkb"`属性并且具有`href="/url?q="`属性的链接。 请注意,这些是硬编码的值,将来可能会更改。 ```java for (String el : result) { System.out.println(el); } ``` 最后,我们将域名打印到终端。 ```java en.wikipedia.org www.space.com www.nasa.gov sk.wikipedia.org www.bbc.co.uk imagine.gsfc.nasa.gov www.forbes.com www.milkywayproject.org www.youtube.com www.universetoday.com ``` 这些是`"Milky Way"`一词的 Google 顶级搜索结果。 本教程专门针对 Jsoup HTML 解析器。 您可能也对相关教程感兴趣: [Java 教程](/lang/java/),[用 Java 读取网页](/articles/javareadwebpage/),[用 Java 阅读文本文件](/articles/javareadtext/)或 [Jtwig 教程](/java/jtwig/)。 列出[所有 Java 教程](/all/#java)。