问题情境:
常常在工作中遇到某一些文字档是由许多编码不同的文字段组成,因为大型爬虫爬下来的各种网页有时候并没有正确的把网页原始编码转换成'utf8',导致大部份文字的编码都是'utf8',但是有少部份的段落为其他编码。
当我需要读取这种文字档做处理并更新写入到另一个档案的时候,要如何才能够避免decode error,并且把非'utf8'编码的字节原封不动写入到另一个档案?
解决方法:
用open的errors参数可以解决这种问题,但是把errors设置成'ignore'和'replace'都会改变非'utf8'编码的文字段,且不可逆,所以无法把非'utf8'编码的字节原封不动写入到另一个档案。
幸好还有另一个选项'surrogateescape'可以设置,他是一个可逆的错误机制处理,把'utf8'无法解析的字元映射成另一种代理字元,这种代理字元的编码段和'utf8'用到的编码段是独立开来的,所以在我们逐行读取时,若发现某一行文字含有这种代理字元的编码段,就可知这行文字无法被'utf8'解析,然后我们就能略过他。
现在我们要把这行含有代理字元编码段的文字转换回来并写入到另一个档案里,那这个新的档案也必须把errors参数设为'surrogateescape',才能有效辨识代理字元编码并将其转换回来。
程式範例:
with open('test.txt','rt',errors='surrogateescape') as rf,\ open('new_test.txt','wt',errors='surrogateescape') as wf: for line in rf: if have_surrogate_char(line): wf.write(line) else: new_line = process(line) wf.write(new_line)