Вопрос, как извлечь текст из HTML с использованием Java просматривалась и дублированные зиллионы раз: Text Extraction from HTML JavaТекст Извлечение из 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());
}
}
}
Теперь я также хотел бы показать номер строки и исходный исходный код html, откуда появился textNode. Я сомневаюсь, что 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? имеет ответ, в котором говорится, что «Иерихон может это сделать», поскольку ссылка выше также указывает. Но указатель на реальный рабочий код отсутствует.
Whith 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
, но теперь проблема Followup что TextExtractor выводит всю текст всех субномов рекурсивно, чтобы текст отображался несколько раз.
Что было бы рабочим решением, которое фильтрует, а также вышеупомянутое решение JSoup (обратите внимание на правильный порядок текстовых элементов), но показывает исходные строки, как это делает фрагмент кода Jericho Code?
Я хотел бы присудить награду вам за ваши усилия. Я не понимаю, найдет ли ваше решение текст в конце тела, как в тесте JUnit моего ответа. Я проверю и вернусь. –
Я рассмотрел ваш вопрос после редактирования. К сожалению, он, похоже, не возвращает текст в правильном порядке. Я реорганизовал его для реализации пакета com.bitplan.texttools; импорт java.util.Список; public interface TextExtractor { \t Список extractTextSegments (String html); }, и он не будет создавать отдельные сегменты, но попытаться объединить весь текст элемента. В этом случае текст в начале тела или div будет помещен вместе с текстом в конце тела или div, а текст в подносах последует позже. Это не то, что сделал фильтр Jsoup. –
Я понял, что у него были ошибки, но, как я упоминаю, это всего лишь пример, чтобы вы начали. Я рад, что вы нашли решение. Повеселись. – alkis