首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Python 用pandas自动化获取表格网页数据

Python 用pandas自动化获取表格网页数据

作者头像
用户11081884
发布2026-07-20 18:33:24
发布2026-07-20 18:33:24
220
举报

在数据采集和分析工作中,经常需要从网页上获取表格数据。传统爬虫方法需要构造请求、解析网页、提取要素等多个步骤,代码量较大。而Pythonpandas库提供了一个非常便捷的函数pd.read_html() ,可以轻松抓取网页上的表格数据,大大简化了爬取表格数据的流程。

Table表格型数据网页结构

pd.read_html() 函数适合抓取HTML中以 <table> 标签结构展示的数据。典型的表格数据结构如下:

代码语言:javascript
复制
<table>
    <thead>
        <tr>
            <th>标题1</th>
            <th>标题2</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>数据1</td>
            <td>数据2</td>
        </tr>
        <tr>
            <td>数据3</td>
            <td>数据4</td>
        </tr>
    </tbody>
</table>

只要网页具有这种结构,就可以使用 pd.read_html() 来抓取数据。

pd.read_html() 函数的工作原理是:

1、向指定的URL或HTML文件发送请求

2、解析HTML内容,查找所有的 <table> 标签

3、将每个表格转换为一个DataFrame

4、返回包含所有DataFrame的列表

使用方法

基本语法

代码语言:javascript
复制
pandas.read_html(io, match='.+', flavor=None, header=None, 
                index_col=None, skiprows=None, attrs=None, 
                parse_dates=False, thousands=',', encoding=None, 
                decimal='.', converters=None, na_values=None, 
                keep_default_na=True, displayed_only=True)

主要参数说明

  • io :接收网址、文件或HTML字符串
  • match :正则表达式,用于匹配特定的表格
  • flavor :解析器,可选’lxml’、’html5lib’
  • header :指定作为列名的行
  • skiprows :跳过的行
  • attrs :属性过滤,如 attrs={’id’: ’table1’}

代码示例

示例1:抓取单页表格数据

代码语言:javascript
复制
import pandas as pd

url = "https://www.stats.gov.cn/sj/xwfbh/fbhwd/202507/t20250715_1960414.html"

try:
    tables = pd.read_html(url, encoding='utf-8')
    # 第一张表即 2024-06 至 2025-06 环比增速
    mom = tables[0]
    print("环比增速(%):")
    print(mom.head(10))
    mom.to_csv("industry_mom_2025.csv", index=False, encoding='utf-8-sig')
except Exception as e:
    print("抓取失败:", e)

示例2:抓取多页表格数据

代码语言:javascript
复制
import pandas as pd
from time import sleep

base_url = ' https://example.com/stock_data?page= {}'
all_data = pd.DataFrame()

for page in range(1, 6):  # 假设抓取5页数据
    url = base_url.format(page)
    try:
        df = pd.read_html(url)[0]  # 获取第一张表格
        all_data = pd.concat([all_data, df])
        print(f'第{page}页抓取成功')
        sleep(1)  # 礼貌性暂停1秒
    except Exception as e:
        print(f'第{page}页抓取失败: {e}')

# 保存所有数据
all_data.to_csv('stock_data_all_pages.csv', index=False)
print('所有数据已保存')

示例3:使用attrs参数精确匹配特定表格

代码语言:javascript
复制
import pandas as pd

url = ' https://example.com/complex_page '
# 只抓取id为'main-table'的表格
table = pd.read_html(url, attrs={'id': 'main-table'})

# 清理数据 - 删除空行和空列
clean_table = table.dropna(how='all').dropna(axis=1, how='all')
print(clean_table.head())

示例4:使用attrs参数精确匹配特定表格

代码语言:javascript
复制
def grab_table(url: str, *, attrs=None, skiprows=None) -> pd.DataFrame | None:
    try:
        tabs = pd.read_html(url, attrs=attrs, skiprows=skiprows, encoding='utf-8')
        return tabs[0].dropna(how='all').dropna(axis=1, how='all')
    except ValueError:
        return None

if __name__ == "__main__":
    df = grab_table("https://example.com/report.html", attrs={"class": "data"})
    if df is not None:
        df.to_csv("report.csv", index=False)

示例5:带登录态抓表:先拿 Cookie 再读表

代码语言:javascript
复制
"""
目标:抓取需登录的「个人成绩表」
思路:① 登录拿 Cookie ② 把 Cookie 塞进后续请求 ③ read_html 解析
"""
importrequests, pandasaspd

login_url = "https://example.com/login"
grade_url = "https://example.com/grade"

sess = requests.Session()
# 1. 登录
sess.post(login_url, data={"username": "me", "password": "pass"}, timeout=10)

# 2. 拿表格
resp = sess.get(grade_url)
tables = pd.read_html(resp.text)      # 支持 io 为字符串
grades = tables[0]
grades.to_csv("my_grades.csv", index=False, encoding='utf-8-sig')

示例6:异步并发:1 分钟下载 200 张「财务报表」表格

代码语言:javascript
复制
"""
200 个 URL 形如 /report/2020 … /report/2219
使用 aiohttp 异步拉取,IO 耗时从 20 min → 1 min
"""
importasyncio, aiohttp, pandasaspd
frompathlibimportPath

BASE = "https://example.com/report/{}"
SAVE = Path("reports")
SAVE.mkdir(exist_ok=True)

asyncdeffetch_save(year: int, session: aiohttp.ClientSession):
    url = BASE.format(year)
    asyncwithsession.get(url) asresp:
        html = awaitresp.text(encoding='utf-8')
        try:
            df = pd.read_html(html)[0]
            df.to_csv(SAVE/f"{year}.csv", index=False)
            print(f"{year}")
        exceptValueError:
            print(f"{year}无表")

asyncdefmain():
    asyncwithaiohttp.ClientSession() assession:
        tasks = [fetch_save(y, session) foryinrange(2020, 2220)]
        awaitasyncio.gather(*tasks)

if__name__ == "__main__":
    asyncio.run(main())

示例7:同一页 N 个表格一键合并:按列对齐

代码语言:javascript
复制
"""
维基百科「各国 GDP」页面含 3 张表,按「国家」列对齐后合并
"""
importpandasaspd

url = "https://en.wikipedia.org/wiki/List_of_countries_by_GDP_(nominal)"
tables = pd.read_html(url, match="Country")      # 只抓表头含 Country 的表

# 统一索引后 concat
merged = (
    pd.concat([t.set_index("Country") fortintables], axis=1)
      .reset_index()
)
merged.to_csv("gdp_merged.csv", index=False)

示例8:增量更新:只抓「昨日以后」的新行

代码语言:javascript
复制
"""
每天凌晨跑批,把官网「每日通报」表追加到本地,重复行自动跳过
"""
importpandasaspd
fromdatetimeimportdatetime, timedelta

LOCAL = "daily_report.csv"
url = "https://example.com/daily"

latest = pd.read_html(url, parse_dates=["Date"])[0]
yesterday = (datetime.today() -timedelta(days=1)).date()
new = latest[latest["Date"].dt.date>yesterday]

ifnew.empty:
    print("无新数据")
else:
    new.to_csv(LOCAL, mode="a", header=notpd.io.common.file_exists(LOCAL), index=False)
    print(f"追加 {len(new)} 行")

示例9:API 兜底:read_html 失败时自动转官方 API

代码语言:javascript
复制
"""
某交易所同时提供「HTML 表格」和 「REST JSON」
HTML 404 时立即切 API,保证脚本不中断
"""
importrequests, pandasaspd

HTML_URL = "https://exchange.com/price.html"
API_URL  = "https://exchange.com/api/v1/price"

defget_price() ->pd.DataFrame:
    try:
        # 优先读表
        returnpd.read_html(HTML_URL, attrs={"id": "price"})[0]
    exceptException:
        # 兜底:调 REST API
        data = requests.get(API_URL, timeout=10).json()
        returnpd.DataFrame(data["list"])   # JSON -> DataFrame

df = get_price()
df.to_csv("price.csv", index=False)

注意事项

1、不是所有网页表格都能用 pd.read_html() 抓取,对静态table场景pandas是高效方案。

2、对于需要登录或反爬虫机制严格的网站,需要配合selenium使用。

3、抓取数据时应注意网站的robots.txt文件和使用条款。

4、大量请求时添加适当的延迟,避免给服务器造成负担。

pd.read_html() Python中一个非常强大的工具,能够用极简的代码实现网页表格数据的抓取。对于数据分析师和爬虫初学者来说,这是一个高效且易于上手的解决方案。对于更复杂的爬取需求,可能需要结合其他工具如requests、BeautifulSoup或selenium来实现。

“无他,惟手熟尔”!有需要就用起来。

如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-09-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Nicholas与Pypi 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Table表格型数据网页结构
  • 使用方法
    • 基本语法
    • 主要参数说明
  • 代码示例
    • 示例1:抓取单页表格数据
    • 示例2:抓取多页表格数据
    • 示例3:使用attrs参数精确匹配特定表格
    • 示例4:使用attrs参数精确匹配特定表格
    • 示例5:带登录态抓表:先拿 Cookie 再读表
    • 示例6:异步并发:1 分钟下载 200 张「财务报表」表格
    • 示例7:同一页 N 个表格一键合并:按列对齐
    • 示例8:增量更新:只抓「昨日以后」的新行
    • 示例9:API 兜底:read_html 失败时自动转官方 API
  • 注意事项
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档