Python使用wb模式写入文件时日文文件名特殊字符丢失问题求助
解决日文文件名下载乱码问题
问题出在content-disposition头的编码解析上:浏览器会自动处理HTTP头中的多语言文件名编码,但你的代码直接用正则提取字符串,没有做编码转换,导致日文被错误解码成乱码。
修复步骤:
- 用
cgi.parse_header解析content-disposition头,拆分出参数部分 - 区分处理
filename和filename*两种参数格式(后者是RFC 5987标准的编码格式,专门用于非ASCII字符) - 对编码后的文件名进行正确解码,转成UTF-8字符串
修改后的代码:
import requests import cgi from urllib.parse import unquote def download_zip(key: str): response = requests.get('some url') if response.status_code == 200: header = response.headers.get('content-disposition') file_name = f"{key}.zip" # 默认文件名 if header: # 解析content-disposition头,拆分主类型和参数 _, params = cgi.parse_header(header) # 优先处理RFC 5987标准的filename*参数 if 'filename*' in params: # filename*格式一般是 "UTF-8''%E9%9F%B3%E3%81%AE%E3%81%AA%E3%81%84%E3%83%AC%E3%83%97%E3%83%AA%E3%82%AB" encoding, _, filename_encoded = params['filename*'].split("''") file_name = unquote(filename_encoded, encoding=encoding) elif 'filename' in params: # 普通filename参数可能是ISO-8859-1编码的,转成UTF-8 filename_raw = params['filename'] file_name = filename_raw.encode('ISO-8859-1').decode('UTF-8') with open(file_name, mode='wb') as f: f.write(response.content) print(f"Written: {file_name}") else: print(f"Failed: {key} -> {response.status_code}")
关键说明:
cgi.parse_header:正确拆分HTTP头的参数部分,避免正则匹配的不严谨filename*:这是HTTP标准中专门为非ASCII文件名定义的参数,格式为编码''编码后的文件名,用unquote解码即可- 普通
filename:很多服务器会把非ASCII文件名用ISO-8859-1编码后放在这个参数里,所以需要先转成字节再用UTF-8解码
这样处理后,就能正确保留日文文件名音のないレプリカ,不会出现乱码。
内容的提问来源于stack exchange,提问作者Catman
相关产品推荐
相关产品推荐

