0

0

如何从混合 ResultSet 中按标题分组提取后续数据

花韻仙語

花韻仙語

发布时间:2026-01-30 11:45:01

|

215人浏览过

|

来源于php中文网

原创

如何从混合 ResultSet 中按标题分组提取后续数据

本文介绍如何在解析无明确结构的 html 表格时,根据 `

` 标题标签中的关键词(如 "mlb")定位,并精准抓取其后所有同级 ` ` 数据行,直到下一个标题 ` ` 出现为止。核心在于合理利用 beautifulsoup 的 `find_next_siblings()` 和状态驱动遍历。

在实际网页爬虫开发中,常会遇到一类“伪多表”结构:整个

内并无独立 分隔,而是通过带标题语义的
(如 "MLB Spring Training - Monday, March 27th")作为逻辑分组标识,其后紧跟若干 表示具体赛事条目,直至下一个同类 出现——这种模式虽不符合标准 HTML 表格规范,却广泛存在于体育赛事、日程公告等动态页面中。

要可靠提取某类分组(如 MLB)下的全部赛事数据,关键在于建立上下文感知的遍历逻辑。以下是两种经过验证的专业方案:

✅ 方案一:基于 find_next_siblings() 的声明式定位(推荐)

该方法语义清晰、可读性强,适用于已知目标

NatAgent
NatAgent

AI数据情报监测与分析平台

下载
易于识别的场景(如含明确文本关键词):
from bs4 import BeautifulSoup

# 假设 soup 已加载完整 HTML
td_headers = soup.find_all('td', class_='head1')  # 精准定位标题行(避免匹配 head1x)
target_keyword = 'MLB'

for td in td_headers:
    if target_keyword in td.get_text():
        # 获取该 
后所有同级兄弟标签,直到下一个 next_ths = [] for sibling in td.find_next_siblings(): if sibling.name == 'td' and 'head1' in sibling.get('class', []): break # 遇到新分组标题,停止收集 if sibling.name == 'th': next_ths.append(sibling) # 解析每个 中的时间与队伍信息 games = [] for th in next_ths: date_div = th.find('div') # 第一个 div 通常是日期 time_div = th.find('div', class_='time') # 时间子 div teams = [div.get_text(strip=True) for div in th.find_all('div') if div != date_div and div != time_div] games.append({ 'date': date_div.get_text(strip=True) if date_div else None, 'time': time_div.get_text(strip=True) if time_div else None, 'teams': teams[:2] if len(teams) >= 2 else teams }) print(f"Found {len(games)} MLB games:") for g in games: print(f" {g['date']} {g['time']} — {' vs '.join(g['teams'])}") break # 仅处理第一个匹配项(如需全部,移除此行)
⚠️ 注意事项: 使用 soup.find_all('td', class_='head1') 而非泛化的 find_all('td'),可避免误匹配 等装饰性单元格; find_next_siblings() 返回的是文档顺序中紧邻的后续兄弟节点,天然符合“标题后连续数据行”的逻辑; break 在遇到下一个 head1 时终止,确保不跨组混入 NHL 或 NBA 数据。

✅ 方案二:单次线性遍历 + 状态机(内存高效)

当 ResultSet 已预先扁平化为 cells = row.find_all(['th','td']) 列表时,推荐用状态变量控制流程,避免重复 DOM 遍历:

cells = []
for row in soup_table.tbody.find_all("tr"):
    cells.extend(row.find_all(['th', 'td']))

mlb_games = []
in_mlb_section = False

for cell in cells:
    # 进入 MLB 分组
    if (cell.name == 'td' 
        and 'head1' in cell.get('class', [])
        and 'MLB' in cell.get_text()):
        in_mlb_section = True
        continue

    # 退出当前分组(遇到任意其他 head1 标题)
    if (cell.name == 'td' 
        and 'head1' in cell.get('class', [])
        and 'MLB' not in cell.get_text()):
        in_mlb_section = False
        continue

    # 收集 MLB 分组内的 th 数据
    if in_mlb_section and cell.name == 'th':
        # 提取时间与队伍(同上)
        date = cell.find('div').get_text(strip=True) if cell.find('div') else ''
        time_el = cell.find('div', class_='time')
        time_str = time_el.get_text(strip=True) if time_el else ''
        teams = [d.get_text(strip=True) for d in cell.find_all('div')[1:]][:2]
        mlb_games.append({'date': date, 'time': time_str, 'teams': teams})

print(f"Extracted {len(mlb_games)} MLB entries.")

? 总结建议

  • 优先使用方案一:代码意图明确,调试友好,适合多数中小型爬虫任务;
  • 方案二适用于流式处理或内存敏感场景:仅遍历一次 DOM,适合超长表格;
  • 始终通过 class 属性(如 'head1')而非标签名做标题判定,提升鲁棒性;
  • 对 get_text() 使用 strip=True 防止空白字符干扰关键词匹配;
  • 若目标站点存在动态加载,需确认 soup 已包含完整渲染后 HTML(必要时集成 Selenium)。

掌握这两种模式,即可灵活应对各类“标题+数据块”混合结构,为体育、金融、课表等垂直领域爬虫打下坚实基础。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

115

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

37

2026.01.26

Python爬虫获取数据的方法
Python爬虫获取数据的方法

Python爬虫可以通过请求库发送HTTP请求、解析库解析HTML、正则表达式提取数据,或使用数据抓取框架来获取数据。更多关于Python爬虫相关知识。详情阅读本专题下面的文章。php中文网欢迎大家前来学习。

293

2023.11.13

java中break的作用
java中break的作用

本专题整合了java中break的用法教程,阅读专题下面的文章了解更多详细内容。

118

2025.10.15

java break和continue
java break和continue

本专题整合了java break和continue的区别相关内容,阅读专题下面的文章了解更多详细内容。

258

2025.10.24

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

469

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.12.06

DOM是什么意思
DOM是什么意思

dom的英文全称是documentobjectmodel,表示文件对象模型,是w3c组织推荐的处理可扩展置标语言的标准编程接口;dom是html文档的内存中对象表示,它提供了使用javascript与网页交互的方式。想了解更多的相关内容,可以阅读本专题下面的文章。

3364

2024.08.14

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

8

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

AngularJS教程
AngularJS教程

共24课时 | 3.1万人学习

CSS教程
CSS教程

共754课时 | 25.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号