You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Jsoup解析HTML时如何处理缺失值避免IndexOutOfBoundsException?

问题描述
  • 开发网页抓取程序,目标元素有两种格式:VALUE1 - VALUE3 或 VALUE1/VALUE2 - VALUE3
  • 对应的HTML结构如下:
    第一种结构:
    <ul>
     <li></li>
     <li></li>
     <li></li>
     <li></li>
     <li></li>
     <li>
          <a><span>VALUE1</span></a>
           -
          <span>VALUE3</span>
                </li>
    </ul>
    
    第二种结构:
    <ul>
          <li></li>
          <li></li>
          <li></li>
          <li></li>
          <li></li>
          <li>
          <a><span>VALUE1</span></a>
           /
          <a><span>VALUE2</span></a>
           -
          <span>VALUE3</span>
                </li>
    </ul>
    
  • 需求是获取每个元素的VALUE1和VALUE3,原代码先把所有VALUE1存入ingDebug1,再把所有VALUE3存入ingDebug2,但VALUE3对应的<span>有时不存在,导致ingDebug2长度小于ingDebug1,合并时触发IndexOutOfBoundsException,需要解决缺失时填充默认值的问题。
  • 原抓取代码:
    for (Element row : parse.select("ul>li>a>span")){ //to scrape the first one
        String ing = row.getAllElements().text();
        ingDebug1.add(ing);
        debug = i;
    }
    
    for (Element row :parse.select("ul>li>span")){ //to scrape the third one
        String ing = row.getAllElements().text();
        debug = i;
    }
    
    for (int k = 0; k<ingDebug1.size(); k++){ // to put them together
        ingShowUp.add(ingDebug1.get(k));
        ingShowUp.add(ingDebug2.get(k));
    }
    
解决方案

核心问题是原代码分别抓取两个独立的元素列表,无法保证每个VALUE1对应一个VALUE3(包括缺失的情况)。正确的做法是遍历每个<li>元素,在每个<li>内部单独提取VALUE1和VALUE3,这样能保证一一对应,即使VALUE3缺失也能填充默认值。

修改后的代码示例:

// 遍历每个li元素,确保每个VALUE1对应处理VALUE3
for (Element li : parse.select("ul>li")) {
    // 提取VALUE1:第一个a标签下的span文本
    Element value1Span = li.selectFirst("a>span");
    String value1 = value1Span != null ? value1Span.text() : "";
    ingDebug1.add(value1);

    // 提取VALUE3:li下的span,但排除a标签内部的span(避免拿到VALUE1/VALUE2的span)
    Element value3Span = li.selectFirst("span:not(a>span)");
    String value3 = value3Span != null ? value3Span.text() : ""; // 缺失时填充空字符串,也可替换为"N/A"等默认值
    ingDebug2.add(value3);
}

// 合并两个列表,此时长度完全一致,不会触发索引越界
for (int k = 0; k < ingDebug1.size(); k++) {
    ingShowUp.add(ingDebug1.get(k));
    ingShowUp.add(ingDebug2.get(k));
}

关键说明

  • 用selectFirst()代替批量选择,确保每个<li>只取对应的第一个VALUE1和目标VALUE3
  • 通过span:not(a>span)选择器精准定位VALUE3的<span>,避免误抓VALUE1/VALUE2的<span>
  • 当元素不存在时,用三元运算符设置默认值,保证ingDebug1和ingDebug2长度完全匹配
  • 若不需要单独维护两个中间列表,也可直接在遍历<li>时将value1和value3直接加入ingShowUp,减少冗余操作

内容的提问来源于stack exchange,提问作者uterkaxx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 23:30:36