使用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
相关产品推荐
相关产品推荐

