如何使用JSOUP解析HTML目录列表中的非结构化数据?
JSoup提取无标签包裹的链接关联信息最优方案
你遇到的场景里,未被HTML标签包裹的日期、时间戳、文件大小,本质是每个<a>标签的前一个紧邻兄弟文本节点,直接通过JSoup的DOM节点关系定位即可,不需要整页正则匹配,是当前场景下效率、准确率最高的方案。
具体实现步骤
- 第一步:用JSoup请求目标页面拿到Document对象,通过选择器筛选出所有指向文件的
<a>标签,避免误抓页面其他无关链接 - 第二步:遍历每个目标
<a>元素,调用previousSibling()方法获取其前序的文本节点,把文本内容去除首尾空白后备用 - 第三步:用正则匹配的方式从处理好的文本中提取日期、时间、文件大小三个字段即可
示例代码
import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.nodes.TextNode; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; public class BlsFileScraper { public static void main(String[] args) throws IOException { // 适配示例格式的正则,可根据实际页面格式调整 Pattern infoPattern = Pattern.compile("(\\d{1,2}/\\d{1,2}/\\d{4})\\s+(\\d{1,2}:\\d{2}\\s+[AP]M)\\s+(\\d+)"); // 替换为实际抓取的页面地址 Document doc = Jsoup.connect("目标页面地址").get(); // 选择所有路径匹配的文件链接,缩小处理范围 for (Element fileLink : doc.select("a[href^=/pub/time.series/]")) { // 获取链接前紧邻的文本节点 TextNode rawInfoNode = (TextNode) fileLink.previousSibling(); String rawInfo = rawInfoNode.text().trim(); Matcher matcher = infoPattern.matcher(rawInfo); if (matcher.find()) { String date = matcher.group(1); String time = matcher.group(2); String fileSize = matcher.group(3); String fileName = fileLink.text(); String fullUrl = fileLink.attr("abs:href"); // 此处可替换为自定义的存储/处理逻辑 System.out.printf("文件名:%s | 链接:%s | 日期:%s | 时间:%s | 文件大小:%s字节%n", fileName, fullUrl, date, time, fileSize); } } } }
方案优势
- 准确率远高于全局正则匹配:依托JSoup构建的DOM树直接通过节点关系定位目标内容,不会被页面其他无关内容干扰
- 性能更优:仅需要遍历目标链接节点,不需要处理整页所有文本内容
- 容错性高:只要DOM节点关系不变,哪怕后续页面空格、换行格式调整,仅需要微调正则即可适配,不需要修改整体抓取逻辑
内容的提问来源于stack exchange,提问作者discord
相关产品推荐
相关产品推荐

