
本文介绍如何利用 pandas.read_html() 直接高效地从 html 网页中提取表格并生成 dataframe,避免手动解析 html 的复杂性与常见错误,特别适用于维基百科等结构清晰的网页。
本文介绍如何利用 pandas.read_html() 直接高效地从 html 网页中提取表格并生成 dataframe,避免手动解析 html 的复杂性与常见错误,特别适用于维基百科等结构清晰的网页。
在网页数据提取实践中,初学者常陷入“手动解析 HTML → 遍历标签 → 拼接列表 → 构造 DataFrame”的冗长流程,不仅代码易错、可维护性差,还容易因页面结构微调(如 class 名变更、嵌套 tbody、空行/合并单元格)而失败——正如原始代码中试图通过 find('table', class_='wikitable sortable') 后再匹配 tbody 并依赖 table_attribs 过滤,实际该属性字典({'Bank name': 'Name', ...})既未用于 BeautifulSoup 查找逻辑,也未处理表头(
)、空行或文本清洗,导致 extracted_data 为空或列数不匹配,最终 DataFrame 构建失败。 更简洁、健壮且符合 Python 数据工程惯例的方式是:直接使用 pandas 内置的 read_html() 函数。它基于 lxml 或 html5lib 自动识别页面中所有
元素,智能解析表头、合并单元格,并返回 list[pd.DataFrame],开箱即用。✅ 正确做法示例(精简可靠): import pandas as pd
import requests
url = 'https://en.wikipedia.org/wiki/List_of_largest_banks#By_market_capitalization'
# 1. 获取网页 HTML 内容
response = requests.get(url)
response.raise_for_status() # 确保请求成功
# 2. 使用 pandas 一键解析所有表格
tables = pd.read_html(response.text)
# 3. 查看共提取到几个表格(维基百科该页面含3个主要表格)
print(f"共找到 {len(tables)} 个表格")
# 4. 定位目标表格:根据标题或内容筛选(推荐)
# 表格0通常是“By market capitalization”部分(验证方式:print(tables[0].head())
df = tables[0]
# 5. 清洗与标准化(关键步骤!)
df.columns = df.columns.str.strip() # 去除列名空格
df = df.dropna(how='all') # 删除全空行
df = df.iloc[:, :2] # 仅保留前两列:银行名 & 市值(按需调整)
df.columns = ['Bank Name', 'Market Cap (US$ Billion)']
df['Market Cap (US$ Billion)'] = pd.to_numeric(
df['Market Cap (US$ Billion)'].str.replace(r'[^\d.]', '', regex=True),
errors='coerce'
)
print(df.head())⚠️ 注意事项:
- pd.read_html() 默认使用 lxml 解析器,若报错请先安装:pip install lxml;
- 维基百科表格常含超链接、注释标记(如 [1]),建议用 .str.extract(r'([^\[]+)') 或正则清洗文本;
- 不要硬编码索引(如 tables[0]),生产环境应结合 match= 参数或遍历 tables 并检查 df.iloc[0,0] 是否含关键词(如 "Bank")来动态定位目标表;
- 若需处理大量网页,建议添加 requests.Session() 复用连接,并设置 headers={'User-Agent': '...'} 防止被拒。
总结:放弃手动 DOM 遍历,拥抱 pandas.read_html() —— 它是网页表格提取的“瑞士军刀”,兼顾简洁性、鲁棒性与可读性。对于学习项目,优先掌握此方法;后续再深入 BeautifulSoup 处理非标准表格或需精细控制的场景。
|