如何使用 Java 从 HTML 中提取文本的问题已被查看和重复了无数次: 从 HTML Java 中提取文本
感谢在 Stackoverflow 上找到的答案,我目前的情况是我正在使用JSoup
<!-- Jsoup maven dependency -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.7.3</version>
</dependency>
和这段或代码:
// parse the html from the givne string
Document doc = Jsoup.parse(html);
// loop over children elements of the body tag
for (Element el:doc.select("body").select("*")) {
// loop over all textnodes of these children
for (TextNode textNode:el.textNodes()) {
// make sure there is some text other than whitespace
if (textNode.text().trim().length()>0) {
// show:
// the original node name
// the name of the subnode witht the text
// the text
System.out.println(el.nodeName()+"."+textNode.nodeName()+":"+textNode.text());
}
}
}
现在我还想显示手头的 textNode 来自的行号和原始 html 源代码。我怀疑 JSoup 可以做到这一点(例如参见)
并尝试解决方法:
int pos = html.indexOf(textNode.outerHtml());
无法可靠地找到原始 html。所以我想我可能不得不切换到另一个库或方法。Jericho-html:是否可以参考源文件中的位置提取文本?正如上面的链接也指出的那样,有一个答案说“杰里科可以做到”。但是缺少指向实际工作代码的指针。
在杰里科,我做到了:
Source htmlSource=new Source(html);
boolean bodyFound=false;
// loop over all elements
for (net.htmlparser.jericho.Element el:htmlSource.getAllElements()) {
if (el.getName().equals("body")) {
bodyFound=true;
}
if (bodyFound) {
TagType tagType = el.getStartTag().getTagType();
if (tagType==StartTagType.NORMAL) {
String text=el.getTextExtractor().toString();
if (!text.trim().equals("")) {
int cpos = el.getBegin();
System.out.println(el.getName()+"("+tagType.toString()+") line "+ htmlSource.getRow(cpos)+":"+text);
}
} // if
} // if
} // for
这已经很好了,因为它会给你这样的输出:
body(normal) line 91: Some Header. Some Text
div(normal) line 93: Some Header
div(normal) line 95: Some Text
但现在的后续问题是 TextExtractor 递归输出所有子节点的整个文本,以便文本多次显示。
什么是过滤以及上述 JSoup 解决方案(请注意文本元素的正确顺序)但显示源代码行的有效解决方案,如上述 Jericho 代码片段一样?