java - Jsoup select 未获取所有元素

标签 java html jsoup

请看下图。红色箭头之前的元素已加载,但其后的 4 个元素由于某种原因未加载。

enter image description here

我选择这些元素的方式是,

doc = Jsoup.connect(url).header("Accept-Encoding", "gzip, deflate").userAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36").maxBodySize(0).timeout(600000).get();

Elements detailsBuyBoxContainer = doc.select("li[class^=product-tile]");
System.out.println(detailsBuyBoxContainer.size());

还尝试使用下面的选择

/*Elements detailsBuyBoxContainer = doc.getElementsByAttributeValueContaining("class",
"details-buy-box-container");*/

打印的尺寸应该是 24 而不是 20

最佳答案

该列表部分由客户端 JavaScript(即 AJAX 调用)填充。 JSoup 不运行 Javascript,也不是浏览器,因此您尝试的简单方法行不通。

我看到两种解决方案:

A) 使用 Selenium webdriver,它是一个真正的浏览器,可以很好地加载 AJAX 内容。

B) 自己识别AJAX调用并使用JSoup直接调用Api url。解释这一点通常并不难,尽管您可能必须使用不同的抓取技术,例如解释 JSON 而不是 HTML。

附录

我进一步研究了 tesco 网站,他们似乎使用了一种有点有趣的方法来发送包含 HTML 的 JSON 响应。我想这可以节省客户端上的一些 JavaScript 工作,但这仍然有点奇怪。那好吧。这是我使用浏览器网络选项卡捕获的调用。当您向下滚动列表时,将进行 Ajax 调用 http://www.tesco.com/direct/blocks/catalog/productlisting/infiniteBrowse.jsp?&view=grid&catId=4294967294+4294814304&sortBy=&searchquery=espresso+机器&offset=20&lazyload=true

看来您需要增加偏移参数才能获得更多结果。此类调用的内容是一个包含两个属性的 JSON 对象:“产品”和“变体”。 products 属性似乎包含 html。

所以一步一步:

1) 使用 Jsoup(或者例如 Apache HttpClient)获取 Ajax 调用的原始内容:

Connection con = Jsoup.connect("http://www.tesco.com/direct/blocks/catalog/productlisting/infiniteBrowse.jsp?&view=grid&catId=4294967294+4294814304&sortBy=&searchquery=espresso+machine&offset=20&lazyload=true")
            .ignoreContentType(true);    
Response res = con.execute();
String rawJSON = res.body();

2) 根据您的喜好使用库解析 JSON。我通常使用Json-Simple

JSONObject o = (JSONObject) JSONValue.parse(html);
String html = (String) o.get("products");

请注意,JSON-Simple 易于使用,但不使用泛型。您可能还想研究 Jackson 的 Gson。

3)使用 JSoup 解析 html:

Document doc = Jsoup.parse(html);

关于java - Jsoup select 未获取所有元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32022167/

相关文章:

javascript - 我对 Focus 事件和 Blur 事件有疑问

java.lang.runtimeException 无法启动 Activity componentInfo

java - Eclipse Tomcat 实例试图从不在源代码中的包初始化 spring bean

java - 如何找到最小值和最大值以查看它们是否匹配?

java - 尝试将数据写入 HCatalog(MapReduce 之外)时出现 InvalidProtocolBufferException

javascript - 将下拉列表中的多选值添加到数组中

Java教程,该程序包含一个错误,但我找不到它

html - CSS处理顺序

android - 在android中显示从JSOUP解析的图像?

android - 允许用户更改 JSOUP URL