[英]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;
}
这是因为某些内容 - 包括您正在寻找的内容 - 是异步创建的,并且不存在于初始 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 中):
post-script processed HTML
。 同样,JSoup 无法检索通过脚本 (JS/AJAX/Angular/React) 发送到浏览器的 HTML,因为它只是一个解析器。"WebView"
( 此处记录),我最近听说(昨天……但它已经出现多年),它将在浏览器中执行脚本,并返回 HTML。 这是一个答案,显示“JavaScript 注入”以从“WebView”实例中检索 DOM 树元素(这是我被告知已完成的方式)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.