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

如何解决从FTP内存读取.xlsx为Pandas DataFrame时的KeyError?

解决从FTP读取xlsx到Pandas DataFrame的报错问题

报错原因分析

KeyError: "There is no item named 'xl/sharedStrings.xml' in the archive" 通常由以下情况导致:

  • 读取了非xlsx格式文件(比如xls、txt、目录等),这类文件不符合xlsx的压缩包结构
  • 循环中复用同一个BytesIO对象,导致多个文件内容叠加,破坏了xlsx的结构
  • 目标xlsx文件本身损坏或为空

针对性解决方案

1. 筛选有效xlsx文件

只处理后缀为.xlsx的文件,同时排除目录(通过文件大小判断,目录的ftp.size()返回None):

# 替换原listff的生成逻辑
listff = []
for f in ftp.nlst():
    try:
        if ftp.size(f) is not None and f.lower().endswith('.xlsx'):
            listff.append(f)
    except ftplib.error_perm:
        # 跳过无权限访问的目录或文件
        continue

2. 每次循环重置BytesIO

避免多个文件内容叠加,在循环内创建新的BytesIO对象,确保每次读取的是单一文件的内容。

3. 指定正确的读取引擎

处理xlsx文件需使用openpyxl引擎,提前执行pip install openpyxl安装依赖。

修改后的完整代码

import ftplib
import pandas as pd
from io import BytesIO

ftp = ftplib.FTP("host") 
ftp.login("ftp_111", "hs12121") 
ftp.dir()

# 筛选有效xlsx文件
listff = []
for f in ftp.nlst():
    try:
        if ftp.size(f) is not None and f.lower().endswith('.xlsx'):
            listff.append(f)
    except ftplib.error_perm:
        continue

for filename in listff:
    try:
        # 每次循环创建新的BytesIO,避免内容污染
        flo = BytesIO()
        ftp.retrbinary(f'RETR {filename}', flo.write, 1024)
        flo.seek(0)
        # 指定openpyxl引擎读取xlsx
        df = pd.read_excel(flo, engine='openpyxl')
        print(f"文件 {filename} 读取成功,DataFrame形状:{df.shape}")
        # 此处添加你的DataFrame处理逻辑
    except Exception as e:
        print(f"处理文件 {filename} 出错: {str(e)}")

额外说明

  • 若需处理xls文件,可单独筛选.xls后缀,使用engine='xlrd'读取(注意xlrd 2.0+版本不再支持xlsx,需安装xlrd<2.0或pyxlsb引擎)
  • 若仍报错,需检查目标xlsx文件是否损坏,可手动下载后验证文件有效性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 15:27:19