JSoup 未从脚本标记中检索 JSON 数据

JSoup doesn't retrieve JSON data from script tag

我正在尝试使用 JSoup (1.13.1) 从 HTML 页面的食谱中获取脚本标签(JSON 数据)中的内容。我不会 post HTML 代码,但脚本标签内容相当大。

每当我尝试打印内容时,我得到一个空字符串。我尝试使用不同的方法获取我的数据:通过选择 ID doc.select("#__NEXT_DATA__"),或使用 doc.select("script[type='application/json']")

如果我尝试遍历所有脚本标签,无论何时到达我想要的脚本标签,它都会打印空白。 我还尝试使用 text() 方法和 toString() 方法打印内容,但它不起作用。我什至看到有人说你可以设置 maxBodySize(0) 但它仍然不起作用。

这是我的代码:

String url = "https://www.marmiton.org/recettes/recette_gateau-au-chocolat-fondant-rapide_166352.aspx";
doc = Jsoup.connect(url).maxBodySize(0).get();

Elements newsHeadlines = doc.select("#__NEXT_DATA__");
                    
for (Element element : newsHeadlines) {
    System.out.println(element);
}

Jsoup 实际上并不解析脚本标签。当它抓取网站时,它会在任何 Javascript 脚本发挥作用之前获取网站的 HTML 来源。因此,当您尝试获取脚本时,它无法识别脚本标签。

对于这种情况,您可能想尝试另一个 API,例如 Selenium

Jsoup 的 text() returns 本应在浏览器中呈现的文本。 'script' 标签根本不会呈现(除非你使用 CSS 技巧!),所以它 returns 是一个空字符串。至少我认为 Jsoup 的 developer/s 是这么想的。

相反,您可以使用 html() 方法,其中 returns 某种 'raw' 文本,IOW 脚本元素内的文本。

将脚本元素视为数据:

Elements newsHeadlines = doc.select("#__NEXT_DATA__");

for (Element element : newsHeadlines) {
    System.out.println(element.data());
}

请注意,某些控制台可能会在显示长度为 81206 个字符的行时出现问题(eclipse 为我做了)(或者数据中有一些内容)所以此代码只是打印出开头...

    for (Element element : newsHeadlines) {
        System.out.println(element.data().length());
        
        int printLen = Math.min(100, element.data().length());
        System.out.println(element.data().substring(0,printLen));
    }

并产生:

81206
{"props":{"pageProps":{"recipeData":{"recipe":{"id":166352,"guid":"7bf48b95-4cd2-4b32-8f41-fb6168510

请注意,如果您可以在您的环境中使用调试器,它会显示该元素一直都有结果,但作为 DataNode 类型的 elementchildNode,这是第一条线索。