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

Java 为什么我的Jsoup代码没有返回正确的元素?,java,android,android-studio,web-scraping,jsoup,Java,Android,Android Studio,Web Scraping,Jsoup,我正在Android Studio中开发一个应用程序,在使用JSoup抓取网页时遇到了一些问题。我已成功连接到网页并返回了一些基本元素来测试库,但现在我无法实际获得我的应用程序所需的元素 我正在尝试获取一些具有“dataat”属性的元素。奇怪的是,返回了一些具有“data at”属性的元素,但不是我要查找的元素。无论出于何种原因,我的代码没有提取网页上共享“data at”属性的所有元素 这是我正在抓取的网页的URL: 包含web刮片代码的方法: Logcat中的结果 我要检索的元素 实际

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

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

这是我正在抓取的网页的URL:

包含web刮片代码的方法: Logcat中的结果

我要检索的元素

实际正在检索的元素之一

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

当您查看页面的源代码时,您会注意到,在运行
document时,
事件中只有17个
数据。querySelector(“[data at]”)将返回29个节点

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

为了克服这个问题,您必须手动获取和解析所需的资源(例如跟踪浏览器发出的AJAX调用),或者使用headless浏览器设置。硒+无头铬就足够了


Letter选项将允许您删除任何可能的web应用程序,包括SPA应用程序,这是使用plaing Jsoup无法实现的。

我不知道该怎么办,但我将再试一次。。。代码中的“问题行”如下所示:

您请求的是
查询字符串
URL
指向包含大量脚本代码的页面。当您加载浏览器并单击按钮(或菜单选项)时,显示为:
“查看源代码”
,您看到的
与JSoup广播和接收的
不完全相同

如果广播的
HTML
包含任何
(您问题中命名的
这些
标记参与了页面的初始加载,那么JSoup将不知道任何有关它的信息。。。它只解析接收到的内容,不能处理任何动态内容

我知道有四种方法可以从动态网页获取“Post Script Loaded”版本的
HTML
,现在我将在这里键入它们。第一种可能是我听说过的最流行的堆栈溢出方法(Java):

  • Selenium将展示该工具如何运行Java脚本。这些是一些。还有就是这里有一个很好的“第一类”,用于使用该工具检索
    脚本处理后的HTML
    。同样,JSoup无法检索通过脚本(JS/AJAX/Angular/React)发送到浏览器的HTML,因为它只是一个解析器
  • puppeter这需要运行一种名为Node.js的语言也许可以从Java调用一个简单的Node.js程序,但这将是一个“两种语言”的解决方案。我从来没用过。这是你想要得到的东西。。。脚本后面的HTML
  • WebViewAndroid Java程序员有一个流行的类,名为
    “WebView”
    (),我最近听说(昨天……但已经过时多年)它将在浏览器中执行脚本并返回HTML。下面显示了从“WebView”实例检索DOM树元素的“JavaScript注入”(我被告知是这样做的)
  • Splash我最喜欢的工具,我想没有人听说过,但对我来说是最简单的。。。所以有一个叫做“Splash API”的A.P.I。这是一个“Java脚本呈现服务”。。。我将在下面发布一段代码片段,展示“Splash工具”如何检索脚本处理后的HTML
运行
Splash API
(仅当您有权访问
docker
加载程序时)。。。您可以启动一个启动服务器,如下所示。这两行代码被输入到一个GCP
(谷歌云平台)
Shell实例中,服务器在没有任何配置的情况下立即启动:

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

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

在您的代码中,只需将字符串前置到您的
URL

”http://localhost:8050/render.html?url=“

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


谢谢安东尼奥斯,我明白你的意思,这回答了我的问题。如果我可以再问一个问题,当你说我可以跟踪所做的AJAX调用时,我非常确定我在Chrome开发工具网络选项卡下找到了该调用,该选项卡包含我正在查找的所有数据。您能提供一个关于如何获取和解析这个AJAX响应的建议吗?与初始URL完全相同:)AJAX调用只不过是普通的HTTP请求。因此,如果浏览器可以做到这一点,那么JSoup(或任何其他http客户端)也可以做到
@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;
    }
    doc = Jsoup.connect(queryString.toString()).get();
    Elements content = doc.select("[data-at]");
String SPLASH_URL = "http://localhost:8050/render.html?url=";
doc = Jsoup.connect(SPLASH_URL + queryString.toString()).get();