如何统计两类XPath间指定节点数量:冰球比赛每节罚牌数统计
冰球赛事每节判罚数量统计可行方案
第一步:缩小定位范围,消除其他元素干扰
由于你提到boxscore-event-ctn和margT40类名被页面其他元素复用,首先需要把查找范围限定在判罚汇总专属区域:
从提供的HTML片段可以看到,所有判罚和节次标签都在id="tabcontent102"下的class="pad40"节点内,你可以先定位到该父节点,后续所有匹配操作都在该节点范围内执行,即可完全排除其他页面元素的干扰。
方案1:XPath直接统计(实现最简单)
不需要处理判罚序号不重置的问题,直接按节点位置关系统计即可:
- 先提取范围内所有节次标签:
//div[@id='tabcontent102']//h3[@class='margT40'],依次获取每个节次的名称 - 对每个节次标签,统计它和下一个节次标签之间的判罚元素数量,对应XPath写法参考:
count(./following-sibling::div[@class='boxscore-event-ctn'] << ./following-sibling::h3[@class='margT40'][1])
如果是最后一个节次,直接统计该标签之后所有判罚元素的数量即可。
方案2:顺序遍历DOM节点(兼容性最高)
不依赖XPath的高级语法,适配各种抓取工具:
- 初始化变量:当前节次名称为空、当前节次判罚计数为0、存储结果的空字典
- 按从上到下的顺序遍历父容器下的所有直属子元素:
- 若当前元素是
h3.margT40:先将上一个节次的统计结果存入字典,再更新当前节次名称为该标签的文本,将计数重置为0 - 若当前元素是
div.boxscore-event-ctn:将当前节次的计数加1
- 若当前元素是
- 遍历完成后,将最后一个节次的统计结果存入字典,就能得到所有节次的判罚数量。
参考代码(Python + BeautifulSoup)
from bs4 import BeautifulSoup # 这里传入你抓取到的判罚区域HTML内容 soup = BeautifulSoup(your_html_content, 'html.parser') # 定位判罚汇总父容器 penalty_container = soup.select_one('#tabcontent102 .pad40') current_period = None current_count = 0 result = {} # 遍历所有直属子元素 for child in penalty_container.children: if child.name == 'h3' and 'margT40' in child.get('class', []): # 遇到新节次,先保存上一节的统计结果 if current_period is not None: result[current_period] = current_count # 重置计数,更新当前节次 current_period = child.get_text(strip=True) current_count = 0 elif child.name == 'div' and 'boxscore-event-ctn' in child.get('class', []): current_count += 1 # 保存最后一节的统计结果 if current_period is not None: result[current_period] = current_count print(result) # 对应你提供的示例HTML,输出为: # {'First Period': 0, 'Second period': 3, 'Third period': 2, 'Overtime': 0}
内容的提问来源于stack exchange,提问作者Matthew S. Berenbaum
相关产品推荐
相关产品推荐

