使用Jsoup选择器获取文本时table元素返回0元素的问题排查
问题分析与解决方案
首先,你的代码出现select.size()=0的问题主要有三个核心原因,我帮你一一拆解:
1. 多余的<tbody>选择器
大多数现代浏览器会自动给表格补全<tbody>标签,但Jsoup是严格按照网页原始HTML解析的。你打开目标网页的源码(F12查看原始HTML,不是浏览器渲染后的DOM)会发现,很多<table>标签下面直接就是<tr>,根本没有<tbody>。所以你的选择器里硬加tbody,自然匹配不到任何元素。
2. 无效的:nth-child(0)选择器
CSS的:nth-child()伪类是从1开始计数的,没有第0个元素。你用td:nth-child(0)这种写法完全无效,这也会导致选择器匹配失败。
3. 选择器路径过于冗长
冗长的路径不仅容易写错,还会因为网页结构的微小变化就完全失效。应该找更稳定的特征标识来定位目标元素。
修正后的代码实现
我帮你重构了代码,简化了选择器,同时解决了上面的所有问题,现在可以正确提取截图里的公交站点名称:
import java.io.IOException; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; public class fetch_bus_stops { public static void main(String[] args) { try { // 模拟真实浏览器请求,降低被反爬拦截的概率 Document doc = Jsoup.connect("http://rozklady.mpk.krakow.pl/?lang=PL&rozklad=20180520&linia=1") .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36") .get(); // 通过特征定位站点行:匹配所有包含带"przystanek"参数链接的表格行 Elements stopRows = doc.select("table tr:has(a[href*=przystanek])"); System.out.println("找到" + stopRows.size() + "个站点"); int index = 1; for(Element row : stopRows) { // 提取站点名称:直接取链接内的span文本 String stopName = row.select("a > span").text(); System.out.println(index + " " + stopName); index++; } } catch (IOException e) { e.printStackTrace(); } } }
关键优化点说明
- 移除多余
tbody:直接用table tr匹配表格行,不依赖浏览器自动生成的<tbody>标签。 - 特征化选择器:
table tr:has(a[href*=przystanek])通过链接的参数特征定位站点行,比冗长的层级路径更稳定。 - 修正索引逻辑:直接通过
a > span提取文本,避免了错误的nth-child(0)写法。 - 优化请求头:使用更贴近真实浏览器的User-Agent,降低被网站拒绝请求的概率。
内容的提问来源于stack exchange,提问作者Pomme De Terre
相关产品推荐
相关产品推荐

