Java 如何使用JSoup构建NodeTraversor/NodeVisitor?
我基本上是一个编程初学者,目前正在尝试使用JSoup构建我的第一个web scraper。到目前为止,我能够从我的目标站点的一个页面获得我想要的数据,但我自然希望以某种方式迭代整个站点 JSoup似乎为此提供了某种类型的遍历器/访问者(有什么区别?),但我完全不知道如何实现这一点。我知道什么是树和节点,知道目标站点的结构,但我不知道如何创建(?)遍历器/访问者对象(?)并让它在我的站点上运行。是不是有一些我不知道的高级Java/oo魔法在起作用 不幸的是,Jsoup食谱和其他线程似乎都没有真正涵盖细节,所以如果有人能把我推向正确的方向,我将非常感激 JSoup似乎提供了某种遍历器/访问者(有什么区别?)Java 如何使用JSoup构建NodeTraversor/NodeVisitor?,java,web-scraping,jsoup,traversal,tree-traversal,Java,Web Scraping,Jsoup,Traversal,Tree Traversal,我基本上是一个编程初学者,目前正在尝试使用JSoup构建我的第一个web scraper。到目前为止,我能够从我的目标站点的一个页面获得我想要的数据,但我自然希望以某种方式迭代整个站点 JSoup似乎为此提供了某种类型的遍历器/访问者(有什么区别?),但我完全不知道如何实现这一点。我知道什么是树和节点,知道目标站点的结构,但我不知道如何创建(?)遍历器/访问者对象(?)并让它在我的站点上运行。是不是有一些我不知道的高级Java/oo魔法在起作用 不幸的是,Jsoup食谱和其他线程似乎都没有真正涵
NodeTraversor
将有效地迭代指定根节点下的所有节点,包括指定根节点。它不使用递归,因此大型DOM不会创建堆栈溢出
(NV)是(NT)的伴侣。每次NT进入一个节点时,它调用NV的head
方法。每次NT离开节点时,它都调用NV的tail
方法
NT已准备就绪,并由Jsoup API提供给您。您所要做的就是为NT提供一个NV实现
下面是NodeVisitor的真实实现,取自:
protected static String convertElementsToText(Elements elements) {
if (elements == null || elements.isEmpty())
return "";
StringBuilder buffer = new StringBuilder();
NodeTraversor nt = new NodeTraversor(new ToTextNodeVisitor(buffer));
for (Element element : elements) {
nt.traverse(element);
}
return buffer.toString().trim();
}
private static final class ToTextNodeVisitor implements NodeVisitor {
final StringBuilder buffer;
ToTextNodeVisitor(StringBuilder buffer) {
this.buffer = buffer;
}
@Override
public void head(Node node, int depth) {
if (node instanceof TextNode) {
TextNode textNode = (TextNode) node;
String text = textNode.text().replace('\u00A0', ' ').trim(); // non breaking space
if (!text.isEmpty()) {
buffer.append(text);
if (!text.endsWith(" ")) {
buffer.append(" ");
}
}
}
}
@Override
public void tail(Node node, int depth) {
}
}