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

Google Drive API批量上传因Latin-1编码错误失败,但单独上传正常

Google Drive API批量上传因Latin-1编码错误失败,但单独上传正常

我之前也碰到过一模一样的问题!本质原因是Google Drive API的批量请求(Batch HTTP)默认使用Latin-1(ISO-8859-1)编码来序列化请求体,而单个文件创建请求默认采用UTF-8编码。当请求体里包含Latin-1无法编码的字符(比如文件名里的特殊符号、或者像\ufffd这种编码替换字符),批量请求就会触发编码错误,而单个请求因为用UTF-8所以能正常工作。

下面给你几个可行的解决方案,按推荐程度排序:

方案1:强制批量请求使用UTF-8编码(最推荐)

直接修改批量请求的Content-Type头部,显式指定UTF-8编码,这样整个batch的请求体都会用UTF-8序列化,彻底解决编码问题。

修改你的批量请求创建代码:

# 原代码
# batch_request = drive_service.new_batch_http_request()

# 修改后的代码
batch_request = drive_service.new_batch_http_request()
# 手动设置batch请求的Content-Type头部,指定UTF-8编码
batch_request._headers['Content-Type'] = 'multipart/mixed; charset=utf-8'

补充说明:

  • 虽然_headers是私有属性,但在当前的Google API Python客户端版本(v2.x)中是稳定可用的;如果担心私有属性的兼容性,也可以通过创建batch时传入回调的方式间接设置,但上面的写法最简单直接。
  • 你之前对文件名的encode('utf-8').decode('utf-8')处理是多余的,直接用os.path.basename(excel_file_path)即可,Python字符串本身就是Unicode编码的。

方案2:预处理文件名,移除/替换Latin-1不支持的字符

如果不想修改batch的默认编码,可以先把文件名里的问题字符(比如\ufffd)替换成Latin-1支持的字符,比如问号?:

for idx, (excel_file_path, _) in enumerate(file_pairs):
    raw_file_name = os.path.basename(excel_file_path)
    # 替换掉Latin-1无法编码的字符
    sanitized_file_name = raw_file_name.replace('\ufffd', '?')
    file_metadata = {
        'name': sanitized_file_name,
        'mimeType': 'application/vnd.google-apps.spreadsheet'
    }
    # 后续代码不变...

这个方案适合临时应急,但如果文件名里有大量特殊字符,还是方案1更彻底。

方案3:补全文件ID收集逻辑(你的原代码遗漏的点)

顺便提一下,你原代码里的file_id_mapping始终是空的,因为没有在batch请求的回调里收集上传后的文件ID。可以通过添加回调函数来完善这部分功能,结合方案1的完整代码如下:

def true_batch_upload_excel_files(file_pairs: List[Tuple[str, str]]) -> Dict[str, str]:
    drive_service = get_drive_service()
    file_id_mapping = {}

    def batch_callback(request_id, response, exception):
        # 回调函数:处理每个批量请求的结果
        if exception:
            print(f"文件上传失败: {exception}")
        else:
            # 关联原文件路径和上传后的Google Drive文件ID
            original_file_path = file_pairs[int(request_id)][0]
            file_id_mapping[original_file_path] = response['id']

    batch_request = drive_service.new_batch_http_request(callback=batch_callback)
    # 强制batch使用UTF-8编码
    batch_request._headers['Content-Type'] = 'multipart/mixed; charset=utf-8'

    for idx, (excel_file_path, _) in enumerate(file_pairs):
        file_metadata = {
            'name': os.path.basename(excel_file_path),
            'mimeType': 'application/vnd.google-apps.spreadsheet'
        }
        media = MediaFileUpload(
            excel_file_path,
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        batch_request.add(
            drive_service.files().create(
                body=file_metadata,
                media_body=media,
                fields='id'
            ),
            request_id=str(idx)  # 给每个请求加ID,方便回调里对应原文件
        )
    try:
        batch_request.execute()
        print("批量上传完成")
    except Exception as e:
        print(f"批量上传出错: {e}")

    return file_id_mapping

额外提示

  • 那个\ufffd字符通常是文件名编码错误导致的(比如系统用了错误的编码解析文件名),如果预处理文件名时发现大量这种字符,建议检查你的文件系统编码是否正确(Windows下通常是GBK/UTF-8,Mac/Linux是UTF-8)。

备注:内容来源于stack exchange,提问作者2_DataCrawlers_Nawaf __

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 18:35:29