java - 如何使用 JSoup 构建 NodeTraversor/NodeVisitor?

标签 java web-scraping jsoup traversal tree-traversal

我几乎是一个编程初学者,目前正在尝试使用 JSoup 构建我的第一个网络抓取工具。到目前为止,我能够从目标网站的单个页面获取所需的数据,但我自然希望以某种方式迭代整个网站。

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

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

最佳答案

JSoup seems to offer some kind of traverser/visitor (what's the difference?)

NodeTraversor将有效地迭代指定根节点下并包括指定根节点的所有节点。它不使用递归,因此大的 DOM 不会创建 stackoverflow。

NodeVisitor (NV) 是 NodeTraversor 的同伴(新界)。 NT 每次进入节点时都会调用 NV 的 head 方法。 NT每次离开节点时,都会调用NV的tail方法。

NT 已准备好并由 Jsoup API 提供给您。您所要做的就是为 NT 提供 NV 实现。

这是 NodeVisitor 的实际实现,取自 ElasticSearch source code :

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

关于java - 如何使用 JSoup 构建 NodeTraversor/NodeVisitor?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37210487/

相关文章:

java - 如何计算三角函数的精确值?

Java 数组到 ArrayList 到数组

python - 为什么 lxml 找不到这个类?

javascript - 在抓取之间暂停 Node 渗透

java - org.jsoup.Jsoup 不处理 javascript 链接?

java - Eclipse 无法识别动态 Web 项目中的 Jsoup JAR 文件

java - 将 Swing 数据库应用程序转换为基于 Web 的应用程序

java - Android(Java)性能问题?

javascript - Python 抓取网站获得 Apache Tomcat/6.0.36 - 错误报告

java - Jsoup 响应 : Every second sign is garbage (encoding issue? )