Java 为什么我的Jsoup代码没有返回正确的元素?
我正在Android Studio中开发一个应用程序,在使用JSoup抓取网页时遇到了一些问题。我已成功连接到网页并返回了一些基本元素来测试库,但现在我无法实际获得我的应用程序所需的元素 我正在尝试获取一些具有“dataat”属性的元素。奇怪的是,返回了一些具有“data at”属性的元素,但不是我要查找的元素。无论出于何种原因,我的代码没有提取网页上共享“data at”属性的所有元素 这是我正在抓取的网页的URL: 包含web刮片代码的方法: Logcat中的结果 我要检索的元素 实际正在检索的元素之一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中的结果 我要检索的元素 实际
这是因为某些内容(包括您正在查找的内容)是异步创建的,并且不存在于初始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();