You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python pd.read_csv读取csv报Too many columns specified错误排查

错误原因
  • 传入pd.read_csv()的目标地址是HTML网页,不是纯文本CSV数据。该页面包含大量HTML标签、前端渲染代码,pandas逐块读取时,碰到不含逗号分隔符的HTML代码行,会判定该行仅1列,和你指定的20个列名数量不匹配,直接触发报错。
  • HURDAT2原始数据本身不是等列数的规整CSV结构:文件内交替存在两类合法行,一类是单条飓风的元信息头行,仅3个有效字段;另一类是逐6小时的观测记录行,才对应你定义的20个字段。直接强制按全文件20列读取,碰到短的头行也会触发列数不匹配错误。
  • 代码里已经定义了专门适配该数据格式的readHURDAT2()解析函数,但后续读取逻辑没有调用这个函数,反而直接用pandas硬读格式不匹配的内容,逻辑冲突。
修复方案
  • 第一步先获取干净的纯文本数据:不要直接把HTML页面地址传给pd.read_csv(),先请求地址拿到页面内容,提取页面中<pre>标签包裹的原始纯文本数据,剔除所有HTML标签垃圾内容。
  • 不要直接用固定列数参数硬读全文件:要么直接复用代码里已经写好的readHURDAT2()函数处理提取到的纯文本数据,拿到结构化结果;要么逐行遍历纯文本内容,先识别行类型:如果是飓风元信息头行就单独存储当前飓风的基础属性,如果是观测记录行再按20个字段拆分,和列名匹配后存入结果集。
  • 不要通过加on_bad_lines='skip'这类参数跳过报错行,这类被判定为“列数不对”的行要么是需要的头行数据,要么是HTML垃圾内容,直接跳过会导致数据缺失或者脏数据混入。

可参考的实现代码:

import requests
import re
import pandas as pd
from io import StringIO

url = 'https://www.aoml.noaa.gov/hrd/hurdat/hurdat2.html'
columnnames= ['list out each of the 20 column names'] # 替换为实际使用的20个列名

# 拉取并清洗出纯数据文本
resp = requests.get(url, timeout=10)
# 提取pre标签内的原始数据,剔除HTML标签
raw_text = re.search(r"<pre>(.*?)</pre>", resp.text, re.S).group(1).strip()

records = []
current_storm = {}
for line in StringIO(raw_text):
    line = line.strip()
    if not line:
        continue
    parts = [i.strip() for i in line.split(",")]
    # 识别飓风头行:以AL/EP/CP开头的ID,共3个有效字段
    if len(parts) >=3 and parts[0][:2] in ("AL", "EP", "CP") and parts[0][2:].isdigit():
        current_storm = {
            "storm_id": parts[0],
            "storm_name": parts[1],
            "track_entry_count": int(parts[2])
        }
    else:
        # 解析观测行,和当前飓风信息合并
        obs_row = dict(zip(columnnames, parts[:len(columnnames)]))
        obs_row.update(current_storm)
        records.append(obs_row)

# 最终拿到结构化的DataFrame
result_df = pd.DataFrame(records)

内容的提问来源于stack exchange,提问作者help_me

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 21:06:34