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

使用API上传Pandas DF至Google Sheets报错,转CSV再转回可解决

问题:Google Sheets API上传DataFrame时部分工作表报SSL EOF错误,转CSV后恢复

我通过Google Sheets API将网页抓取结果(存储在Pandas DataFrame)上传至同一份电子表格的多个工作表,大部分工作表正常,但有两个始终失败。移除try/except后得到ssl.SSLEOFError错误,而将DataFrame转存为CSV再重新读取后,就能成功上传。想知道原因,以及不用这个 workaround 的解决方案。

上传代码

def df_to_sheet(sheet, sheetName, df):
   try:
       df.replace(np.nan, '', inplace=True)
       df = df.T.reset_index().T.values.tolist()
       inputRange = sheetName + '!A1'

       response = sheet.values().update(
           spreadsheetId=sheets_conn.SPREADSHEET_ID,
           valueInputOption='RAW',
           range=inputRange,
           body=dict(
               majorDimension='ROWS',
               values=df
               )
       ).execute()
       print(response)
       return True
   except:
       return False

报错信息

File "/usr/lib/python3/dist-packages/httplib2/__init__.py", line 1725, in request
    (response, content) = self._request(
  File "/usr/lib/python3/dist-packages/httplib2/__init__.py", line 1441, in _request
    (response, content) = self._conn_request(conn, request_uri, method, body, headers)
  File "/usr/lib/python3/dist-packages/httplib2/__init__.py", line 1364, in _conn_request
    conn.request(method, request_uri, body, headers)
  File "/usr/lib/python3.10/http/client.py", line 1282, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/lib/python3.10/http/client.py", line 1328, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.10/http/client.py", line 1277, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.10/http/client.py", line 1076, in _send_output
    self.send(chunk)
  File "/usr/lib/python3.10/http/client.py", line 998, in send
    self.sock.sendall(data)
  File "/usr/lib/python3.10/ssl.py", line 1236, in sendall
    v = self.send(byte_view[count:])
  File "/usr/lib/python3.10/ssl.py", line 1205, in send
    return self._sslobj.write(data)
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:2396)

临时解决方法(转CSV)

i = 0
if (df_to_sheet(sheet, sheetName, df)):
     print("Sheet Posted:   ", sheetName)
else:
     print("No Sheet Posted:", sheetName)
     df.to_csv(csv_path + str(i), index=False)
     df = pd.read_csv(csv_path + str(i))
     if (df_to_sheet(sheet, sheetName, df)):
          print("Sheet Posted using workaround: ", sheetName)
     else:
          print("Still no Sheet Posted", sheetName)
     i += 1

原因分析

转CSV再读取的核心作用是清洗DataFrame中的特殊数据类型和隐藏格式问题:

  • 网页抓取的DataFrame可能包含Pandas特殊数据类型(如带时区的datetime64、category类型、NaT时间缺失值),这些类型直接转列表时,序列化过程会生成不符合API期望的格式,导致HTTP请求数据包异常,触发SSL连接中断。
  • CSV是纯文本格式,写入再读取会强制将所有数据转换为字符串或基础数值类型,自动丢弃Pandas的元数据和特殊类型标记。
  • 同时,这个过程会自动过滤网页抓取带来的非标准控制字符、编码异常字符,这类字符可能干扰API请求的数据包传输,引发SSL EOF错误。

无需CSV的解决方案

直接在原DataFrame上做针对性清洗:

  1. 统一数据类型:将非基础类型列转为字符串
import pandas as pd
import numpy as np

# 遍历列,把特殊数据类型转成字符串
for col in df.columns:
    if df[col].dtype not in ['int64', 'float64', 'object']:
        df[col] = df[col].astype(str)
  1. 清理特殊字符:移除控制字符和非标准空白符
import re

# 对每个单元格清理非打印字符
df = df.applymap(
    lambda x: re.sub(r'[\x00-\x1F\x7F]', '', str(x)) if pd.notna(x) else ''
)
  1. 替换所有特殊缺失值:覆盖NaN之外的缺失标记
df = df.replace([pd.NA, pd.NaT, np.inf, -np.inf], '', regex=True)
  1. 优化DataFrame转列表的逻辑:避免T.reset_index().T的复杂操作,直接用更简洁的方式保留表头和数据:
# 替换原代码中的df = df.T.reset_index().T.values.tolist()
values = [df.columns.tolist()] + df.values.tolist()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 05:50:28