Java 如何使用JSoup构建NodeTraversor/NodeVisitor?

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食谱和其他线程似乎都没有真正涵

我基本上是一个编程初学者,目前正在尝试使用JSoup构建我的第一个web scraper。到目前为止,我能够从我的目标站点的一个页面获得我想要的数据,但我自然希望以某种方式迭代整个站点

JSoup似乎为此提供了某种类型的遍历器/访问者(有什么区别?),但我完全不知道如何实现这一点。我知道什么是树和节点,知道目标站点的结构,但我不知道如何创建(?)遍历器/访问者对象(?)并让它在我的站点上运行。是不是有一些我不知道的高级Java/oo魔法在起作用

不幸的是,Jsoup食谱和其他线程似乎都没有真正涵盖细节,所以如果有人能把我推向正确的方向,我将非常感激

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) {
    }
}