为什么我的 Jsoup 代码没有返回正确的元素?
Why is my Jsoup Code not Returning the Correct Elements?
我正在 Android Studio 中开发一个应用程序,但在使用 JSoup 进行网页抓取时遇到了一些问题。我已成功连接到网页并返回了一些基本元素来测试库,但现在我无法真正获得我的应用程序所需的元素。
我正在尝试获取一些具有“data-at”属性的元素。奇怪的是,返回了一些具有“data-at”属性的元素,但不是我正在寻找的元素。无论出于何种原因,我的代码都没有提取 all 网页上共享“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
次出现,而返回 运行ning document.querySelector("[data-at]")
29 个节点。
您在JSoup 中能够得到的是页面的静态内容(初始DOM)。您将无法获取动态创建的内容,因为您不需要 运行 必需的 JS 脚本。
为了克服这个问题,您将不得不手动获取和解析所需资源(例如跟踪浏览器发出的 AJAX 调用)或使用无头浏览器设置。 Selenium + headless Chrome 应该足够了。
Letter 选项将允许您抓取任何可能的 Web 应用程序,包括 SPA 应用程序,这是使用 plaing Jsoup 无法实现的。
我不太清楚该怎么办,但我会再试一次...您代码中的“有问题的行”是这些:
doc = Jsoup.connect(queryString.toString()).get();
Elements content = doc.select("[data-at]");
这是您请求的 queryString
- URL
指向包含的页面相当多的脚本代码。当您加载浏览器并单击显示以下内容的按钮(或 menu-option)时:"View Source"
,HTML
你看到的与 JSoup 广播和接收的 HTML
不完全相同。
如果广播的HTML
中包含任何<SCRIPT TYPE="text/javascript"> ... </SCRIPT>
(以及命名的URL
在你的问题中确实如此),AND 那些 <SCRIPT>
标签参与了页面的初始加载,那么 JSoup 将对此一无所知... 它仅解析接收到的内容,无法处理任何动态内容。
我知道有四种方法可以从动态 web-page,我现在就在这里打字。第一种可能是我在 Stack Overflow 上听说过的最流行的方法(在 Java 中):
- SeleniumThis Answer will show how the tool can run Java-Script. These are some Selenium Docs. And then there is this page这里有一个很棒的“第一个class”,用于使用该工具检索
post-script processed HTML
。同样,JSoup 无法检索通过脚本 (JS/AJAX/Angular/React) 发送到浏览器的 HTML,因为它 只是一个解析器 .
- Puppeteer 这需要 运行ning 一种叫做 Node.js 的语言也许调用一个简单的 Node.js 来自 Java 的程序可以工作,但这将是一个“双语言”解决方案。我从来没有用过它。这是 an answer 显示获取,某种程度上,您想要获取什么...脚本后的 HTML。
- WebViewAndroidJava程序员有一个流行的class叫做
"WebView"
(documented here), that I have recently been told about (yesterday ... but it has been out for years) that will execute script in a browser, and return the HTML. Here is an answer 显示“Java脚本注入”以从“WebView”实例中检索 DOM 树元素(这是我被告知完成的方式)
- Splash 我最喜欢的工具,我认为没有人听说过,但对我来说是最简单的...所以有一个 A.P.I .称为“Splash API”。这是“Java-Script 呈现服务”的 their explanation。自从我一直在使用这个...我将 post 一个代码片段,展示“Splash Tool”如何检索
post-script processed HTML
下面。
至 运行 Splash API
(仅当您有权访问 docker
loading program) ... 你启动一个 Splash Server
如下。将这两行输入到 GCP (Google Cloud Platform)
Shell 实例中,服务器无需任何配置即可启动:
Pull the image:
$ sudo docker pull scrapinghub/splash
Start the container:
$ sudo docker run -it -p 8050:8050 --rm scrapinghub/splash
In your code, just prepend the String to your 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();
我正在 Android Studio 中开发一个应用程序,但在使用 JSoup 进行网页抓取时遇到了一些问题。我已成功连接到网页并返回了一些基本元素来测试库,但现在我无法真正获得我的应用程序所需的元素。
我正在尝试获取一些具有“data-at”属性的元素。奇怪的是,返回了一些具有“data-at”属性的元素,但不是我正在寻找的元素。无论出于何种原因,我的代码都没有提取 all 网页上共享“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
次出现,而返回 运行ning document.querySelector("[data-at]")
29 个节点。
您在JSoup 中能够得到的是页面的静态内容(初始DOM)。您将无法获取动态创建的内容,因为您不需要 运行 必需的 JS 脚本。
为了克服这个问题,您将不得不手动获取和解析所需资源(例如跟踪浏览器发出的 AJAX 调用)或使用无头浏览器设置。 Selenium + headless Chrome 应该足够了。
Letter 选项将允许您抓取任何可能的 Web 应用程序,包括 SPA 应用程序,这是使用 plaing Jsoup 无法实现的。
我不太清楚该怎么办,但我会再试一次...您代码中的“有问题的行”是这些:
doc = Jsoup.connect(queryString.toString()).get(); Elements content = doc.select("[data-at]");
这是您请求的 queryString
- URL
指向包含的页面相当多的脚本代码。当您加载浏览器并单击显示以下内容的按钮(或 menu-option)时:"View Source"
,HTML
你看到的与 JSoup 广播和接收的 HTML
不完全相同。
如果广播的HTML
中包含任何<SCRIPT TYPE="text/javascript"> ... </SCRIPT>
(以及命名的URL
在你的问题中确实如此),AND 那些 <SCRIPT>
标签参与了页面的初始加载,那么 JSoup 将对此一无所知... 它仅解析接收到的内容,无法处理任何动态内容。
我知道有四种方法可以从动态 web-page,我现在就在这里打字。第一种可能是我在 Stack Overflow 上听说过的最流行的方法(在 Java 中):
- SeleniumThis Answer will show how the tool can run Java-Script. These are some Selenium Docs. And then there is this page这里有一个很棒的“第一个class”,用于使用该工具检索
post-script processed HTML
。同样,JSoup 无法检索通过脚本 (JS/AJAX/Angular/React) 发送到浏览器的 HTML,因为它 只是一个解析器 . - Puppeteer 这需要 运行ning 一种叫做 Node.js 的语言也许调用一个简单的 Node.js 来自 Java 的程序可以工作,但这将是一个“双语言”解决方案。我从来没有用过它。这是 an answer 显示获取,某种程度上,您想要获取什么...脚本后的 HTML。
- WebViewAndroidJava程序员有一个流行的class叫做
"WebView"
(documented here), that I have recently been told about (yesterday ... but it has been out for years) that will execute script in a browser, and return the HTML. Here is an answer 显示“Java脚本注入”以从“WebView”实例中检索 DOM 树元素(这是我被告知完成的方式) - Splash 我最喜欢的工具,我认为没有人听说过,但对我来说是最简单的...所以有一个 A.P.I .称为“Splash API”。这是“Java-Script 呈现服务”的 their explanation。自从我一直在使用这个...我将 post 一个代码片段,展示“Splash Tool”如何检索
post-script processed HTML
下面。
至 运行 Splash API
(仅当您有权访问 docker
loading program) ... 你启动一个 Splash Server
如下。将这两行输入到 GCP (Google Cloud Platform)
Shell 实例中,服务器无需任何配置即可启动:
Pull the image:
$ sudo docker pull scrapinghub/splash
Start the container:
$ sudo docker run -it -p 8050:8050 --rm scrapinghub/splash
In your code, just prepend the String to your
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();