解决老旧服务器端多语言网站文件名乱码问题:以 DART 网站为例
引言
在用 Python 爬取多语言网站(如韩文、日文等)的内容时,文件名乱码是一个常见问题。近日,我在爬取韩国 DART(Data Analysis, Retrieval and Transfer System)网站(https://dart.fss.or.kr)的文件(PDF 和 ZIP)时,遇到了文件名乱码问题。服务器返回的 Content-Disposition 头中的文件名显示为 [LIG³Ø½º¿ø]...,而预期为 [LIG넥스원]...。本文将分析乱码原因,分享解决思路,并总结通过代码获取网站内容时需要前期手动获取的关键信息,帮助开发者在处理多语言文件名时少走弯路。
问题描述
DART 网站提供公司披露文件的下载接口,包括 PDF(通过 pdf.do)和 ZIP(通过 zip.do)。我的目标是从 listzip_zip.txt 文件读取下载链接,将文件保存到本地 ./files 目录,文件名需添加 rcp_no_ 前缀,并正确显示韩文。
初始代码逻辑如下:
- 使用
requests.Session发送 GET 请求,获取文件。 - 从
Content-Disposition头提取文件名。 - 保存文件,保留原始文件名。
代码片段(简化版):
import requests
import re
url = 'https://dart.fss.or.kr/pdf/download/zip.do?rcp_no=20250429800466&dcm_no=10620925'
response = requests.get(url)
content_disposition = response.headers.get('content-disposition')
if content_disposition:
match = re.search(r'filename="([^"]+)"', content_disposition)
if match:
filename = match.group(1)
print(f"Raw filename: {
filename}")
else:
filename = "default.zip"
运行结果:
- 日志显示文件名乱码:
Raw filename: [LIG³Ø½º¿ø]±â¾÷¼³¸íȸ(IR)°³ÃÖ(¾È³»°ø½Ã)(2025.04.29).zip - 预期文件名:
[LIG넥스원]기업설명회(IR)개최(안내공시)(2025.04.29).zip - 浏览器 InPrivate 模式下载的文件名显示正确,表明服务器返回的编码可能非标准。
问题分析
1. 服务器编码非标准
Content-Disposition 头的 filename 参数包含乱码,表明服务器未遵循 HTTP 标准(RFC 5987)。标准建议:
- 使用
filename*参数以 UTF-8 编码,例如:Content-Disposition: attachment; filename*=UTF-8''%5BLIG%EB%84%A5%EC%8A%A4%EC%9B%90%5D... - 或确保
filename参数的编码与客户端期望一致(通常为 UTF-8)。
DART 服务器的行为:
- 使用
filename参数,未使用filename*。 - 韩文字符(如
넥)的 UTF-8 字节序列(EB 84 A5)被错误地作为 Latin-1(ISO-8859-1)发送,导致乱码(如³Ø)。 - 例如:
넥(UTF-8:EB 84 A5)在 Latin-1 中被解析为³Ø½(对应字节EB 84 A5)。
- 这表明服务器未正确处理多语言字符,可能将 UTF-8 字符串直接作为 Latin-1 写入头。
2. 浏览器与代码的差异
- 浏览器:Edge 等浏览器通过启发式解码(heuristic decoding)尝试多种编码(如 UTF-8、CP949),正确显示文件名。
- 代码:Python 的
requests库直接接收Content-Disposition的原始字节,需手动解码,否则显示乱码。
3. 编码模式推断
通过调试,我提取了 Raw filename 的字节序列:
raw_filename = "[LIG³Ø½º¿ø]..."
print(raw_filename.encode('latin1'))
# 输出: b'[LIG\xeb\x84\xa5\xec\x8a\xa4\xec\x9b\x90]...'
- 字节序列
EB 84 A5 EC 8A A4 EC 9B 90符合 UTF-8 编码,对应韩文넥스원。 - 尝试解码:
print(raw_filename.encode('latin1').decode('utf-8')) # 输出: [LIG넥스원]... - 确认服务器将 UTF-8 字节序列误作为 Latin-1 发送。
4. 非标准编码的普遍性
这种乱码问题在多语言网站中常见,尤其在:
- 历史遗留系统,未针对国际化(i18n)优化。
- 使用区域编码(如韩文的 CP949)而非 UTF-8。
- 未遵循 RFC 5987,未使用
filename*。
解决思路
1. 多编码解码逻辑
- 方案:针对
filename实现多编码解码,优先尝试latin1 -> utf-8,后备latin1 -> cp949和 RFC 2047 解码。 - 代码:

最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



