说明:pandas 读取网页表格依赖
read_html(),底层是解析页面里<table>标签,不是爬虫接口,只适合提取静态表格;JS动态渲染表格该方法读不到。
1. 环境安装
# 两个解析引擎二选一,推荐 lxml 速度更快
pip install pandas lxml
# 备选:html5lib(容错更强,适合不规范网页)
# pip install html5lib
2. 基础语法
pd.read_html(
io,
match=".+", # 匹配表格文本,筛选目标表
flavor="lxml", # 解析引擎 lxml / html5lib
header=None, # 指定哪一行作为表头
index_col=None, # 指定索引列
skiprows=None, # 跳过行
attrs=None, # 根据table标签属性筛选 table attrs
converters=None, # 列数据转换
na_values=None,
keep_default_na=True
)
返回值:DataFrame列表,一个网页里可能有多个 <table>,每一个对应一个df。
3. 最简单示例:直接读取网页URL
import pandas as pd
url = "[https://example-table-url.com](https://example-table-url.com)"
# 读取页面所有table
df_list = pd.read_html(url, flavor="lxml")
print(f"一共找到 {len(df_list)} 个表格")
# 取第1个表格
df = df_list[0]
print(df.head())
4. 读取本地HTML文件
import pandas as pd
# 读取本地html文件
df_list = pd.read_html("table.html", flavor="lxml")
df = df_list[0]
print(df)
本地示例 table.html 内容:
<table border="1">
<tr><th>姓名</th><th>年龄</th><th>城市</th></tr>
<tr><td>张三</td><td>22</td><td>杭州</td></tr>
<tr><td>李四</td><td>25</td><td>上海</td></tr>
</table>
5. 进阶筛选技巧
5.1 match 匹配包含指定文字的表格
页面很多表格,只取包含“销量”的那张表
df_list = pd.read_html(url, match="销量", flavor="lxml")
df = df_list[0]
5.2 attrs 根据table属性筛选
# 只读取 <table class="data-table">
df_list = pd.read_html(url, attrs={"class": "data-table"}, flavor="lxml")
5.3 指定表头、跳过行
# 第0行作为表头,跳过前1行
df_list = pd.read_html(url, header=0, skiprows=[0], flavor="lxml")
6. 读取字符串里的HTML表格
适合拿到html片段直接解析
import pandas as pd
html_text = """
<table>
<tr><th>id</th><th>name</th></tr>
<tr><td>1</td><td>apple</td></tr>
<tr><td>2</td><td>banana</td></tr>
</table>
"""
df_list = pd.read_html(html_text)
df = df_list[0]
print(df)
7. 读取后保存到 Excel / CSV
df.to_excel("html_table_result.xlsx", index=False)
df.to_csv("html_table_result.csv", index=False, encoding="utf-8-sig")
8. 常见坑 & 限制(重点)
- JS渲染表格读不到
read_html不会执行JS。网页是Vue/React动态渲染、点击加载表格 → pandas读不到,需要用 Selenium / Playwright 拿到渲染完成后的html源码再传给read_html。
Playwright 简易示例:
from playwright.sync_api import sync_playwright
import pandas as pd
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto(url)
html = page.content()
df_list = pd.read_html(html)
browser.close()
- 网页有反爬、需要Cookie、登录态:
read_html不支持请求头,需要先用requests拿到html源码
import requests
import pandas as pd
headers = {"User-Agent":"Mozilla/5.0"}
resp = requests.get(url, headers=headers)
df_list = pd.read_html(resp.text)
- 合并单元格:pandas读取后会自动填充,和网页显示有差异,需要自己清洗
- 表格嵌套、复杂合并、分页表格:
read_html能力弱,优先选专门爬虫解析(BeautifulSoup)
9. 清洗示例:去除空行、重置索引
df = df.dropna(how="all") # 删除全空行
df = df.reset_index(drop=True)
10. 完整综合代码(requests + read_html + 导出)
import pandas as pd
import requests
url = "xxx"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
res = requests.get(url, headers=headers, timeout=10)
res.raise_for_status()
tables = pd.read_html(res.text, match="", flavor="lxml")
print(f"表格数量:{len(tables)}")
target_df = tables[0]
print(target_df.head())
target_df.to_excel("output_html_table.xlsx", index=False)
0 条笔记