1. 概述
Jsoup 是一个开源的HTML解析库,主要用于网页数据抓取。它提供了基于DOM API的数据解析、提取和操作功能,简单粗暴又实用。
本文将演示如何使用Jsoup解析HTML表格,包括:
- ✅ 读取表格数据
- ✅ 更新表格内容
- ✅ 动态添加/删除表格行
2. 依赖配置
在项目中添加Jsoup依赖(Maven配置):
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.17.2</version>
</dependency>
最新版本可在Maven中央仓库获取。
3. 表格结构
我们使用以下HTML表格结构作为示例(完整代码见文末GitHub仓库):
<table>
<thead>
<tr>
<th>Name</th>
<th>Maths</th>
<th>English</th>
<th>Science</th>
</tr>
</thead>
<tbody>
<tr>
<td>Student 1</td>
<td>90</td>
<td>85</td>
<td>92</td>
</tr>
</tbody>
</table>
⚠️ 注意:本文假设表格遵循标准结构(thead
包含表头,tbody
包含数据行),且不存在colspan
/rowspan
等复杂合并单元格。
4. 解析表格数据
4.1 基础解析逻辑
通过CSS选择器快速定位表格元素:
Element table = doc.select("table").get(0); // 获取第一个表格
Elements rows = table.select("tr"); // 获取所有行
Elements headers = rows.get(0).select("th,td"); // 获取表头
4.2 完整解析方法
public List<Map<String, String>> parseTable(Document doc, int tableOrder) {
Element table = doc.select("table").get(tableOrder);
Element tbody = table.select("tbody").get(0);
Elements dataRows = tbody.select("tr");
Elements headerRow = table.select("tr").get(0).select("th,td");
// 提取表头
List<String> headers = new ArrayList<>();
for (Element header : headerRow) {
headers.add(header.text());
}
// 解析数据行
List<Map<String, String>> parsedData = new ArrayList<>();
for (Element row : dataRows) {
Elements cells = row.select("th,td");
Map<String, String> rowData = new HashMap<>();
for (int i = 0; i < cells.size(); i++) {
rowData.put(headers.get(i), cells.get(i).text());
}
parsedData.add(rowData);
}
return parsedData;
}
4.3 数据结构说明
使用List<Map<String, String>>
存储解析结果:
- ✅ 列表索引 = 行号
- ✅ Map键 = 列名(表头)
- ✅ Map值 = 单元格内容
4.4 单元测试验证
@Test
public void whenDocumentTableParsed_thenTableDataReturned() {
JsoupTableParser parser = new JsoupTableParser();
Document doc = parser.loadFromFile("Students.html");
List<Map<String, String>> tableData = parser.parseTable(doc, 0);
assertEquals("90", tableData.get(0).get("Maths"));
}
5. 更新表格数据
5.1 单元格更新方法
// 更新文本内容
colVals.get(index).text("新值");
// 更新HTML内容(支持标签)
colVals.get(index).html("<b>新值</b>");
5.2 批量更新实现
public void updateTableData(Document doc, int tableOrder, String newValue) {
Element table = doc.select("table").get(tableOrder);
Elements dataRows = table.select("tbody tr");
for (Element row : dataRows) {
Elements cells = row.select("th,td");
for (Element cell : cells) {
cell.text(newValue); // 统一更新所有单元格
}
}
}
5.3 更新测试验证
@Test
public void whenTableUpdated_thenUpdatedDataReturned() {
JsoupTableParser parser = new JsoupTableParser();
Document doc = parser.loadFromFile("Students.html");
parser.updateTableData(doc, 0, "50");
List<Map<String, String>> tableData = parser.parseTable(doc, 0);
assertEquals("50", tableData.get(2).get("Maths"));
}
6. 添加表格行
6.1 动态添加行实现
public void addRowToTable(Document doc, int tableOrder) {
Element table = doc.select("table").get(tableOrder);
Element tbody = table.select("tbody").get(0);
// 获取列数
int colCount = table.select("tr").get(0).select("th,td").size();
// 创建新行
Element newRow = new Element("tr");
for (int i = 0; i < colCount; i++) {
newRow.appendElement("td").text("11"); // 设置默认值
}
// 添加到表格
tbody.appendChild(newRow);
}
6.2 添加行测试验证
@Test
public void whenTableRowAdded_thenRowCountIncreased() {
JsoupTableParser parser = new JsoupTableParser();
Document doc = parser.loadFromFile("Students.html");
int initialCount = parser.parseTable(doc, 0).size();
parser.addRowToTable(doc, 0);
int newCount = parser.parseTable(doc, 0).size();
assertEquals(initialCount + 1, newCount);
}
7. 删除表格行
7.1 删除行实现
public void deleteRowFromTable(Document doc, int tableOrder, int rowIndex) {
Element table = doc.select("table").get(tableOrder);
Elements rows = table.select("tbody tr");
if (rowIndex < rows.size()) {
rows.get(rowIndex).remove(); // 直接移除行元素
}
}
7.2 删除行测试验证
@Test
public void whenTableRowDeleted_thenRowCountDecreased() {
JsoupTableParser parser = new JsoupTableParser();
Document doc = parser.loadFromFile("Students.html");
int initialCount = parser.parseTable(doc, 0).size();
parser.deleteRowFromTable(doc, 0, 2); // 删除第3行
int newCount = parser.parseTable(doc, 0).size();
assertEquals(initialCount - 1, newCount);
}
8. 总结
通过Jsoup可以高效实现HTML表格的完整操作:
- ✅ 数据解析:CSS选择器+Map结构存储
- ✅ 内容更新:支持文本/HTML两种更新方式
- ✅ 动态修改:轻松实现行级增删操作
⚠️ 踩坑提示:处理复杂表格(合并单元格/嵌套表格)时需额外处理DOM结构,建议先用浏览器开发者工具分析目标表格结构。
完整示例代码见GitHub仓库:jsoup-table-parser-demo