#+title: 使用 Python 获取文件正确的编码 #+date: <2024-04-11 Thu 16:51> #+author: thebesttv Python 的 [[https://docs.python.org/3/library/functions.html#open][=open()=]] 函数 默认用 [[https://docs.python.org/3/library/locale.html#locale.getencoding][=locale.getencoding()=]] 来确定编码, 正常默认返回 UTF-8。 但有的文件可能是 latin1 之类的编码,就会寄掉。 根据[[https://stackoverflow.com/q/436220/11938767][这个问题]]下面的回答,目前确定文件编码的方法: - 先用 magic 确定文件是否为二进制 - 不直接使用 magic 的结果,因为可能有误报 (即返回是 UTF-8,但真正读取的时候还是会报错) - 如果不是二进制,再用 bs4 的 UnicodeDammit 来获取正确编码 #+begin_src python import magic from bs4 import UnicodeDammit def get_file_encoding_magic(file_path): # https://stackoverflow.com/a/16203777/11938767 with open(file_path, 'rb') as f: blob = f.read() m = magic.open(magic.MAGIC_MIME_ENCODING) m.load() encoding = m.buffer(blob) # "utf-8" "us-ascii" etc return encoding def get_file_encoding_bs4(file_path): # https://stackoverflow.com/a/60858982/11938767 with open(file_path, 'rb') as file: blob = file.read() suggestion = UnicodeDammit(blob) return suggestion.original_encoding def get_file_encoding(file_path): # 先用 magic 判断文件是否为二进制 coarse_encoding = get_file_encoding_magic(file_path) if coarse_encoding == 'binary': return 'binary' # 对于非二进制,用 bs4 获取编码。因为 magic 会有误报 return get_file_encoding_bs4(file_path) #+end_src 以及写了一个[[https://gist.github.com/thebesttv/a14d7793d2de5c94fe4202c1c3fabce3][脚本]], 用来列出当前目录下所有非 UTF-8 / ASCII 编码的文件。