【发布时间】:2014-11-21 06:35:52
【问题描述】:
如何使用 Java 从 HTML 中提取文本的问题已被查看和重复了无数次: Text Extraction from HTML Java
Thanks to 在 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 可以做到这一点 (e.g. see)
并尝试解决方法:
int pos = html.indexOf(textNode.outerHtml());
无法可靠地找到原始 html。所以我想我可能不得不切换到另一个图书馆或方法。 Jericho-html: is it possible to extract text with reference to positions in source file? 的答案是“杰里科可以做到”,因为上面的链接也指出了这一点。但是缺少指向实际工作代码的指针。
我在 Jericho 那里得到了:
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 Code sn-p 那样显示源代码行的有效解决方案?
【问题讨论】:
标签: java html html-parsing jsoup jericho-html-parser