本文目录导读:

我来为您提供几个Jsoup解析的实用案例,从基础到进阶。
基础案例:HTML解析入门
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class BasicExample {
public static void main(String[] args) {
// 1. 解析HTML字符串
String html = "<html><head><title>示例页面</title></head>"
+ "<body>"
+ "<div class='content'>"
+ " <h1>标题</h1>"
+ " <p class='text'>第一段文本</p>"
+ " <p class='text'>第二段文本</p>"
+ " <a href='https://example.com'>链接</a>"
+ "</div>"
+ "</body></html>";
Document doc = Jsoup.parse(html);
// 获取标题
String title = doc.title();
System.out.println("页面标题: " + title);
// 通过类名获取元素
Elements paragraphs = doc.getElementsByClass("text");
for (Element p : paragraphs) {
System.out.println("段落内容: " + p.text());
}
// 通过标签获取
Element heading = doc.selectFirst("h1");
System.out.println("H1内容: " + heading.text());
// 获取链接
Element link = doc.selectFirst("a");
System.out.println("链接文本: " + link.text());
System.out.println("链接地址: " + link.attr("href"));
}
}
抓取示例
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
public class WebScraper {
public static void main(String[] args) {
try {
// 连接并获取网页
Document doc = Jsoup.connect("https://example.com/news")
.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
.timeout(10000)
.get();
// 提取新闻标题和链接
Elements newsItems = doc.select("div.news-item");
System.out.println("找到 " + newsItems.size() + " 条新闻\n");
for (Element item : newsItems) {
// 获取标题
Element title = item.selectFirst("h2.title");
// 获取链接
Element link = item.selectFirst("a");
// 获取摘要
Element summary = item.selectFirst("p.summary");
if (title != null) {
System.out.println("标题: " + title.text());
}
if (link != null) {
System.out.println("URL: " + link.attr("href"));
}
if (summary != null) {
System.out.println(" " + summary.text());
}
System.out.println("---");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
表格数据提取
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class TableParser {
// 定义数据模型
static class Student {
String name;
int age;
String grade;
@Override
public String toString() {
return String.format("学生{姓名='%s', 年龄=%d, 班级='%s'}",
name, age, grade);
}
}
public static void main(String[] args) {
String html = "<html><body>"
+ "<table id='student-table'>"
+ " <thead>"
+ " <tr><th>姓名</th><th>年龄</th><th>班级</th></tr>"
+ " </thead>"
+ " <tbody>"
+ " <tr><td>张三</td><td>18</td><td>高三(1)班</td></tr>"
+ " <tr><td>李四</td><td>17</td><td>高三(2)班</td></tr>"
+ " <tr><td>王五</td><td>18</td><td>高三(1)班</td></tr>"
+ " </tbody>"
+ "</table>"
+ "</body></html>";
Document doc = Jsoup.parse(html);
List<Student> students = parseTable(doc);
System.out.println("解析结果:");
students.forEach(System.out::println);
}
private static List<Student> parseTable(Document doc) {
List<Student> students = new ArrayList<>();
// 选择表格数据行(跳过表头)
Elements rows = doc.select("#student-table tbody tr");
for (Element row : rows) {
Elements cells = row.select("td");
if (cells.size() >= 3) {
Student student = new Student();
student.name = cells.get(0).text();
student.age = Integer.parseInt(cells.get(1).text());
student.grade = cells.get(2).text();
students.add(student);
}
}
return students;
}
}
复杂选择器示例
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class SelectorExamples {
public static void main(String[] args) {
String html = "<html><body>"
+ "<div id='main'>"
+ " <ul class='nav'>"
+ " <li class='active'><a href='/home'>首页</a></li>"
+ " <li><a href='/products'>产品</a></li>"
+ " <li><a href='/about'>关于我们</a></li>"
+ " </ul>"
+ " <div class='content'>"
+ " <p data-id='1'>第一个段落</p>"
+ " <p data-id='2' class='highlight'>第二个段落</p>"
+ " <p data-id='3'>第三个段落</p>"
+ " </div>"
+ "</div>"
+ "</body></html>";
Document doc = Jsoup.parse(html);
System.out.println("=== 选择器示例 ===\n");
// 1. ID选择器
Element mainDiv = doc.selectFirst("#main");
System.out.println("ID选择器 #main: " + mainDiv.tagName());
// 2. 类选择器
Elements activeItems = doc.select(".active");
System.out.println("类选择器 .active: " + activeItems.size() + " 个元素");
// 3. 属性选择器
Elements withDataId = doc.select("[data-id]");
System.out.println("属性选择器 [data-id]: " + withDataId.size() + " 个元素");
// 4. 组合选择器
Elements navLinks = doc.select("ul.nav > li > a");
System.out.println("组合选择器: " + navLinks.size() + " 个链接");
// 5. 包含文本选择
Elements paragraphWithText = doc.select("p:contains(第二个)");
System.out.println("文本选择: " + paragraphWithText.text());
// 6. 相邻兄弟选择器
Element highlight = doc.selectFirst(".highlight");
Element nextParagraph = highlight.nextElementSibling();
System.out.println("相邻兄弟: " + nextParagraph.text());
// 7. 父元素查找
Element paragraph = doc.selectFirst("p");
Element parentDiv = paragraph.parent();
System.out.println("父元素: " + parentDiv.className());
// 8. 第一个和最后一个
Element firstP = doc.selectFirst("p:first-child");
Element lastP = doc.selectFirst("p:last-child");
System.out.println("第一个p: " + firstP.text());
System.out.println("最后一个p: " + lastP.text());
}
}
处理相对URL和文件下载
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
public class ImageDownloader {
public static void main(String[] args) {
try {
// 设置baseUri用于解析相对路径
String baseUrl = "https://example.com/gallery";
Document doc = Jsoup.connect(baseUrl).get();
// 处理图片链接
Elements images = doc.select("img");
for (Element img : images) {
// 获取图片地址(相对路径转绝对路径)
String src = img.absUrl("src");
// 获取alt文本(用于文件名)
String alt = img.attr("alt");
String fileName = alt.isEmpty() ?
"image_" + System.currentTimeMillis() :
alt.replace(" ", "_");
System.out.println("图片地址: " + src);
System.out.println("文件名: " + fileName);
// 下载图片(可选)
// downloadImage(src, "downloads/" + fileName + ".jpg");
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static void downloadImage(String imageUrl, String savePath)
throws IOException {
// 创建目录
Files.createDirectories(Paths.get(savePath).getParent());
// 下载并保存
try (InputStream in = new URL(imageUrl).openStream()) {
Files.copy(in, Paths.get(savePath));
}
System.out.println("图片已保存: " + savePath);
}
}
处理表单数据
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.FormElement;
import org.jsoup.nodes.Element;
import java.io.IOException;
import java.util.Map;
public class FormProcessor {
public static void main(String[] args) {
try {
// 1. 提交GET请求
Document doc = Jsoup.connect("https://httpbin.org/get")
.data("username", "zhangsan")
.data("age", "25")
.get();
System.out.println("GET请求响应:");
System.out.println(doc.body().text());
// 2. 提交POST请求
Connection.Response response = Jsoup.connect("https://httpbin.org/post")
.data("username", "lisi")
.data("password", "123456")
.method(Connection.Method.POST)
.execute();
Document responseDoc = response.parse();
System.out.println("\nPOST请求响应:");
System.out.println(responseDoc.body().text());
// 3. 模拟表单提交
String html = "<form id='login-form' action='/login' method='post'>"
+ "<input type='text' name='username' value=''>"
+ "<input type='password' name='password' value=''>"
+ "<button type='submit'>登录</button>"
+ "</form>";
Document formDoc = Jsoup.parse(html);
// 获取表单
Element form = formDoc.selectFirst("#login-form");
// 模拟填写表单
form.selectFirst("input[name=username]").val("张三");
form.selectFirst("input[name=password]").val("abc123");
// 提交表单
// 实际项目中会发送到指定action地址
System.out.println("\n表单数据:");
Elements inputs = form.select("input");
for (Element input : inputs) {
System.out.println(input.attr("name") + " = " + input.val());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用Cookies保持会话
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
import java.util.Map;
public class SessionHandler {
public static void main(String[] args) {
Connection connection = Jsoup.connect("https://example.com/login");
try {
// 1. 登录获取cookies
Connection.Response loginResponse = connection
.data("username", "admin")
.data("password", "123456")
.method(Connection.Method.POST)
.execute();
// 获取cookies
Map<String, String> cookies = loginResponse.cookies();
System.out.println("登录成功,Cookies: " + cookies);
// 2. 使用cookies访问需要认证的页面
Document protectedPage = Jsoup.connect("https://example.com/dashboard")
.cookies(cookies)
.get();
System.out.println("受保护页面标题: " + protectedPage.title());
// 3. 保持会话状态(多次请求)
Connection.Response firstRequest = Jsoup.connect("https://example.com/api/data")
.cookies(cookies)
.execute();
// 后续请求自动携带cookies
Connection.Response secondRequest = Jsoup.connect("https://example.com/api/more")
.cookies(cookies)
.execute();
} catch (IOException e) {
e.printStackTrace();
}
}
}
异常处理最佳实践
import org.jsoup.HttpStatusException;
import org.jsoup.Jsoup;
import org.jsoup.UnsupportedMimeTypeException;
import org.jsoup.nodes.Document;
import java.io.IOException;
public class ErrorHandling {
public static void main(String[] args) {
String[] urls = {
"https://example.com",
"https://nonexistent-site.com",
"https://example.com/not-found",
"https://example.com/file.pdf" // 非HTML内容
};
for (String url : urls) {
try {
fetchUrl(url);
} catch (HttpStatusException e) {
System.out.println("HTTP状态错误: " + url);
System.out.println("状态码: " + e.getStatusCode());
} catch (UnsupportedMimeTypeException e) {
System.out.println("不支持的MIME类型: " + url);
} catch (IOException e) {
System.out.println("IO错误: " + url);
System.out.println("原因: " + e.getMessage());
} catch (Exception e) {
System.out.println("未知错误: " + url);
e.printStackTrace();
}
System.out.println("---");
}
}
private static void fetchUrl(String url) throws IOException {
Document doc = Jsoup.connect(url)
.userAgent("Mozilla/5.0")
.timeout(5000)
.followRedirects(true)
.ignoreHttpErrors(false)
.get();
System.out.println("成功获取: " + url);
System.out.println("标题: " + doc.title());
}
}
使用建议
-
添加依赖 (Maven):
<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.16.1</version> </dependency>
-
性能优化:
- 使用连接池复用连接
- 合理设置超时时间
- 限制并发请求数量
-
反爬虫处理:
- 设置合理的User-Agent
- 添加请求间隔
- 使用代理IP
-
数据提取规范:
- 优先使用id选择器
- 避免过度使用链式选择器
- 对optional元素进行空值检查
这些案例覆盖了Jsoup的主要功能,您可以根据实际需求进行调整和扩展,如果您有特定的使用场景,我可以提供更针对性的示例。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播