从 JSoup 选择器中过滤掉格式化标签
Filtering out formatting tags from JSoup selectors
JSoup 这里。我有以下 HTML 我正在尝试解析:
<html><head>
<title>My Soup Materials</title>
<!--mstheme--><link rel="stylesheet" type="text/css" href="../../_themes/ice/ice1011.css"><meta name="Microsoft Theme" content="ice 1011, default">
</head>
<body><center><table width="92%"><tbody>
<tr>
<td><h2>My Soup Materials</h2>
<table width="100%%" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td align="left"><b>Origin:</b> Belgium</td>
<td align="left"><b>Count:</b> 2 foos</td>
</tr>
<tr>
<td align="left"><b>Supplier:</b> </td>
<td align="left"><b>Must Burninate:</b> Yes</td>
</tr>
<tr>
<td align="left"><b>Type:</b> Fizzbuzz</td>
<td align="left"><b>Add Afterwards:</b> No</td>
</tr>
</tbody>
</table>
<br>
<b><u>Notes</b></u><br>Drink more ovaltine</td>
</tr>
</tbody>
</table>
</center></body>
</html>
不幸的是,它实际上有点格式错误(缺少一些结束标签,<b>
和 <u>
上的开始和结束标签不正常,等等)但我希望 JSoup 可以处理这个问题。我无法控制 HTML.
我有以下 Java model/POJO:
@Data // lombok; adds ctors, getters, setters, etc.
public class Material {
private String name;
private String origin;
private String count;
private String supplier;
private Boolean burninate;
private String type;
private Boolean addAfterwards;
}
我正在尝试让 JSoup 解析此 HTML 并从该解析中提供一个 Material
实例。
要抓取里面的数据 <table>
我已经很接近了:
Material material = new Material();
Elements rows = document.select("table").select("tr");
for (Element row : rows) {
// row 1: origin & count
Elements cols = row.select("td");
for (Element col : cols) {
material.setOrigin(???);
material.setCount(???);
}
}
所以我能够得到每个 <tr>
,并且对于每个 <tr>
得到它的所有 <td>
列。但是我挂断的地方是:
<td align="left"><b>Origin:</b> Belgium</td>
因此第一个 <td>
的 col.text()
将是 <b>Origin:</b> Belgium
。 如何告诉 JSoup 我只想要“比利时”?
我认为您正在寻找 tdNode.ownText()
。也有简单的 text()
,但是 as the docs state 这结合了节点 及其所有子节点 的所有文本节点并将它们标准化。换句话说,tdNode.text()
给你字符串 "Origin: Belgium"
。 tdNode.ownText()
只给你 "Belgium"
而 tdNode.child(0).ownText()
只给你 "Origin:"
.
您也可以使用 wholeText()
,它是非规范化的,但我认为您需要此处的规范化(主要涉及去除空格)。
JSoup 这里。我有以下 HTML 我正在尝试解析:
<html><head>
<title>My Soup Materials</title>
<!--mstheme--><link rel="stylesheet" type="text/css" href="../../_themes/ice/ice1011.css"><meta name="Microsoft Theme" content="ice 1011, default">
</head>
<body><center><table width="92%"><tbody>
<tr>
<td><h2>My Soup Materials</h2>
<table width="100%%" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td align="left"><b>Origin:</b> Belgium</td>
<td align="left"><b>Count:</b> 2 foos</td>
</tr>
<tr>
<td align="left"><b>Supplier:</b> </td>
<td align="left"><b>Must Burninate:</b> Yes</td>
</tr>
<tr>
<td align="left"><b>Type:</b> Fizzbuzz</td>
<td align="left"><b>Add Afterwards:</b> No</td>
</tr>
</tbody>
</table>
<br>
<b><u>Notes</b></u><br>Drink more ovaltine</td>
</tr>
</tbody>
</table>
</center></body>
</html>
不幸的是,它实际上有点格式错误(缺少一些结束标签,<b>
和 <u>
上的开始和结束标签不正常,等等)但我希望 JSoup 可以处理这个问题。我无法控制 HTML.
我有以下 Java model/POJO:
@Data // lombok; adds ctors, getters, setters, etc.
public class Material {
private String name;
private String origin;
private String count;
private String supplier;
private Boolean burninate;
private String type;
private Boolean addAfterwards;
}
我正在尝试让 JSoup 解析此 HTML 并从该解析中提供一个 Material
实例。
要抓取里面的数据 <table>
我已经很接近了:
Material material = new Material();
Elements rows = document.select("table").select("tr");
for (Element row : rows) {
// row 1: origin & count
Elements cols = row.select("td");
for (Element col : cols) {
material.setOrigin(???);
material.setCount(???);
}
}
所以我能够得到每个 <tr>
,并且对于每个 <tr>
得到它的所有 <td>
列。但是我挂断的地方是:
<td align="left"><b>Origin:</b> Belgium</td>
因此第一个 <td>
的 col.text()
将是 <b>Origin:</b> Belgium
。 如何告诉 JSoup 我只想要“比利时”?
我认为您正在寻找 tdNode.ownText()
。也有简单的 text()
,但是 as the docs state 这结合了节点 及其所有子节点 的所有文本节点并将它们标准化。换句话说,tdNode.text()
给你字符串 "Origin: Belgium"
。 tdNode.ownText()
只给你 "Belgium"
而 tdNode.child(0).ownText()
只给你 "Origin:"
.
您也可以使用 wholeText()
,它是非规范化的,但我认为您需要此处的规范化(主要涉及去除空格)。