繁体   English   中英

为什么我的 Jsoup 代码没有返回正确的元素?

[英]Why is my Jsoup Code not Returning the Correct Elements?

我正在 Android Studio 中开发一个应用程序,并且在使用 JSoup 进行网络抓取时遇到了一些问题。 我已成功连接到网页并返回了一些基本元素来测试库,但现在我实际上无法获得我的应用程序所需的元素。

我正在尝试获取许多具有“data-at”属性的元素。 奇怪的是,返回了一些具有“data-at”属性的元素,但不是我正在寻找的元素。 无论出于何种原因,我的代码都没有提取网页上共享“data-at”属性的所有元素。

这是我正在抓取的网页的 URL: https : //express.liatoyotaofcolonie.com/inventory? f = dealer.name%3ALia%20Toyota%20of%20Colonie & f = submodel%3ACamry & f = trim%3ALE & f = year% 3A2020

包含网页抓取代码的方法:

@Override
    protected String doInBackground(Void... params) {
        String title = "";
        Document doc;
        Log.d(TAG, queryString.toString());
        try {
            doc = Jsoup.connect(queryString.toString()).get();
            Elements content = doc.select("[data-at]");
            for (Element e: content) {
                Log.d(TAG, e.text());
            }
        } catch (IOException e) {
            Log.e(TAG, e.toString());
        }
        return title;
    }

Logcat 中的结果

在此处输入图片说明

我要检索的元素

在此处输入图片说明

实际被检索的元素之一

在此处输入图片说明

这是因为某些内容 - 包括您正在寻找的内容 - 是异步创建的,并且不存在于初始 DOM (Javascript ;))

当您查看页面的源代码时,您会注意到只有 17 个data-at ,而运行document.querySelector("[data-at]")会返回 29 个节点。

您可以在 JSoup 中获得的是页面的静态内容(初始 DOM)。 您将无法获取动态创建的内容,因为您没有运行所需的 JS 脚本。

为了克服这个问题,您必须手动获取和解析所需的资源(例如跟踪浏览器进行了哪些 AJAX 调用)或使用无头浏览器设置。 Selenium + Headless Chrome 应该就够了。

Letter 选项将允许您抓取任何可能的 Web 应用程序,包括 SPA 应用程序,这是使用普通 Jsoup 无法实现的。

我不太知道该怎么办,但我会再试一次......你的代码中的“问题行”是这些:

 doc = Jsoup.connect(queryString.toString()).get(); Elements content = doc.select("[data-at]");

它是您请求的queryString - URL指向包含相当多脚本代码的页面。 当你加载了一个浏览器,然后单击读取按钮(或者菜单选项)的"View Source"时, HTML你看到的是不一样的确切的HTML广播到和JSoup好评。

如果广播的HTML中包含任何<SCRIPT TYPE="text/javascript"> ... </SCRIPT> (并且您问题中的命名URL确实如此),并且这些<SCRIPT>标记涉及初始加载页面,那么 JSoup 就不会知道它的任何内容......它只解析它接收到的内容,它不能处理任何动态内容。

我知道有四种方法可以从动态网页中获取HTML的“Post Script Loaded”版本,现在我将在此处输入它们。 第一个可能是我在 Stack Overflow 上听说过的最流行的方法(在 Java 中):

  • Selenium This Answer将展示该工具如何运行 Java-Script。 这些是一些Selenium 文档 然后是这个页面,这里有一个很棒的“一流”,用于使用该工具检索post-script processed HTML 同样,JSoup 无法检索通过脚本 (JS/AJAX/Angular/React) 发送到浏览器的 HTML,因为它只是一个解析器
  • Puppeteer这需要运行一种叫做Node.js的语言 也许从 Java 调用一个简单的Node.js程序是可行的,但这将是一个“双语言”解决方案。 我从来没有用过它。 这是一个答案,它显示了您正在尝试获得的内容......脚本后的 HTML。
  • WebView Android Java 程序员有一个流行的类,称为"WebView"此处记录),我最近听说(昨天……但它已经出现多年),它将在浏览器中执行脚本,并返回 HTML。 这是一个答案,显示“JavaScript 注入”以从“WebView”实例中检索 DOM 树元素(这是我被告知已完成的方式)
  • Splash我最喜欢的工具,我想没有人听说过它,但对我来说是最简单的……所以有一个 API 叫做“Splash API”。 这是他们对“Java-Script Rendering Service”的解释 因为我一直在使用这个......我将发布一个代码片段,展示“Splash Tool”如何在下面检索post-script processed HTML

要运行Splash API (仅当您有权访问docker加载程序时)……您如下启动一个Splash Server 这两行被输入到 GCP (Google Cloud Platform) Shell 实例中,服务器直接启动,无需任何配置:

拉取镜像:
$ sudo docker pull scrapinghub/splash

启动容器:
$ sudo docker run -it -p 8050:8050 --rm scrapinghub/splash

在您的代码中,只需将字符串添加到您的URL's
"http://localhost:8050/render.html?url="

因此,在您的代码中,您将使用以下命令(改为),脚本将(更有可能)加载您未找到的所有 HTML 元素:

 String SPLASH_URL = "http://localhost:8050/render.html?url="; doc = Jsoup.connect(SPLASH_URL + queryString.toString()).get();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM