Python 如何确定文本的编码?
我收到一些经过编码的文本,但我不知道使用了什么字符集。有没有一种方法可以使用Python确定文本文件的编码?处理C#。在一般情况下,原则上不可能确定文本文件的编码。因此,没有标准的Python库可以为您做到这一点Python 如何确定文本的编码?,python,encoding,text-files,Python,Encoding,Text Files,我收到一些经过编码的文本,但我不知道使用了什么字符集。有没有一种方法可以使用Python确定文本文件的编码?处理C#。在一般情况下,原则上不可能确定文本文件的编码。因此,没有标准的Python库可以为您做到这一点 如果您对文本文件有更具体的了解(例如,它是XML),则可能有库函数。如果您知道文件的某些内容,您可以尝试使用多种编码对其进行解码,并查看缺少哪些。一般来说,没有办法,因为文本文件是文本文件,而这些文件很愚蠢;) EDIT:chardet似乎没有标记,但大部分答案都适用。检查是否有替代方
如果您对文本文件有更具体的了解(例如,它是XML),则可能有库函数。如果您知道文件的某些内容,您可以尝试使用多种编码对其进行解码,并查看缺少哪些。一般来说,没有办法,因为文本文件是文本文件,而这些文件很愚蠢;) EDIT:chardet似乎没有标记,但大部分答案都适用。检查是否有替代方案 始终正确检测编码是不可能的 (摘自chardet常见问题解答:) 但是,有些编码是优化的 对于特定语言,以及 它们不是随机的。某个人物 序列总是弹出,而 其他序列没有意义。A. 英语流利的人,开一家公司 报纸和发现“txzqJv 2!dasd0a QqdKjvz“将立即意识到这一点 那不是英语(尽管是) 完全由英文字母组成)。 通过研究大量的“典型”文本 计算机算法可以模拟这种情况 有点流利,做一个受过教育的人 猜测文本的语言 有一个图书馆利用这项研究来检测编码。chardet是Mozilla中自动检测代码的一个端口 您也可以使用。它将尝试以下方法:
- 在文档本身中发现的编码:例如,在XML声明或(对于HTML文档)http等价元标记中。如果Beautiful Soup在文档中找到这种编码,它会从一开始就再次解析文档,并尝试使用新的编码。唯一的例外是,如果您显式指定了一种编码,并且该编码确实有效:那么它将忽略在文档中找到的任何编码
- 通过查看文件的前几个字节嗅探到的编码。如果在此阶段检测到编码,它将是UTF-*编码、EBCDIC或ASCII之一
- 库嗅探到的编码(如果已安装)
- UTF-8
- Windows-1252
#!/bin/bash
#
tmpfile=$1
echo '-- info about file file ........'
file -i $tmpfile
enca -g $tmpfile
echo 'recoding ........'
#iconv -f iso-8859-2 -t utf-8 back_test.xml > $tmpfile
#enca -x utf-8 $tmpfile
#enca -g $tmpfile
recode CP1250..UTF-8 $tmpfile
您可能希望通过以循环的形式打开并读取文件来检查编码。。。但您可能需要先检查文件大小:
#PYTHON
encodings = ['utf-8', 'windows-1250', 'windows-1252'] # add more
for e in encodings:
try:
fh = codecs.open('file.txt', 'r', encoding=e)
fh.readlines()
fh.seek(0)
except UnicodeDecodeError:
print('got unicode error with %s , trying different encoding' % e)
else:
print('opening the file with encoding: %s ' % e)
break
计算编码的另一个选项是使用 (哪一个是密码 命令)。有大量的 python绑定可用 位于文件源代码树中的python绑定可用作 (或) debian软件包。它可以通过执行以下操作来确定文件的编码:
导入魔法
blob=open('unknown-file','rb')。read()
m=magic.open(magic.magic\u MIME\u编码)
m、 加载()
编码=m.buffer(blob)#“utf-8”“us ascii”等
pypi上有一个名称相同但不兼容的pip包,它也使用libmagic
。它还可以通过执行以下操作获得编码:
导入魔法
blob=open('unknown-file','rb')。read()
m=magic.magic(mime\u编码=True)
编码=来自缓冲区(blob)的m
根据您的平台,我只选择使用linux shell文件
命令。这对我来说很有用,因为我在一个脚本中使用它,这个脚本只在我们的一台linux机器上运行
显然,这不是一个理想的解决方案或答案,但它可以根据您的需要进行修改。在我的例子中,我只需要确定一个文件是否为UTF-8
import subprocess
file_cmd = ['file', 'test.txt']
p = subprocess.Popen(file_cmd, stdout=subprocess.PIPE)
cmd_output = p.stdout.readlines()
# x will begin with the file type output as is observed using 'file' command
x = cmd_output[0].split(": ")[1]
return x.startswith('UTF-8')
下面是一个读取和获取面值a
chardet
编码预测的示例,如果文件较大,则从文件中读取n行
chardet
还提供了它的编码预测的概率(即置信度
)(还没有查看它们是如何得出的),它与它的预测一起从chardet.predict()
返回,因此如果您愿意,您可以以某种方式使用它
def predict_encoding(file_path, n_lines=20):
'''Predict a file's encoding using chardet'''
import chardet
# Open the file as binary data
with open(file_path, 'rb') as f:
# Join binary lines for specified number of lines
rawdata = b''.join([f.readline() for _ in range(n_lines)])
return chardet.detect(rawdata)['encoding']
此站点有用于识别ascii、使用bom编码和utf8无bom的python代码:。将文件读入字节数组(数据):。这里有一个例子。我在osx
#!/usr/bin/python
import sys
def isUTF8(data):
try:
decoded = data.decode('UTF-8')
except UnicodeDecodeError:
return False
else:
for ch in decoded:
if 0xD800 <= ord(ch) <= 0xDFFF:
return False
return True
def get_bytes_from_file(filename):
return open(filename, "rb").read()
filename = sys.argv[1]
data = get_bytes_from_file(filename)
result = isUTF8(data)
print(result)
PS /Users/js> ./isutf8.py hi.txt
True
#/usr/bin/python
导入系统
def isUTF8(数据):
尝试:
解码=数据。解码('UTF-8')
除UNICEDECODEERROR外:
返回错误
其他:
对于已解码的信道:
如果0xD800这可能会有帮助
from bs4 import UnicodeDammit
with open('automate_data/billboard.csv', 'rb') as file:
content = file.read()
suggestion = UnicodeDammit(content)
suggestion.original_encoding
#'iso-8859-1'
使用linuxfile-i
命令
import subprocess
file = "path/to/file/file.txt"
encoding = subprocess.Popen("file -bi "+file, shell=True, stdout=subprocess.PIPE).stdout
encoding = re.sub(r"(\\n)[^a-z0-9\-]", "", str(encoding.read()).split("=")[1], flags=re.IGNORECASE)
print(encoding)
您可以使用` python magic package,它不会将整个文件加载到内存中:
导入魔法
def检测(
文件路径,
):
回归魔法,魔法(
mime_encoding=True,
).from_文件(文件路径)
输出是编码名称,例如:
- iso-8859-1
- 美国ascii码
- utf-8
感谢您的chardet
参考资料。看起来不错,虽然有点慢。@rillo:没有所谓的“编码标准”。文本编码和计算机一样古老,它是随着时间和需求而有机地发展起来的,这是没有计划的。“Unicode”试图解决这个问题。从各方面考虑,这并不是一个坏主意。我想知道的是,我如何找出打开的文本文件是用什么编码的?@邓布利多我说的是,一直正确地检测它是不可能的。你所能做的只是猜测,但有时它可能会失败,它不会每次都起作用,因为编码不是真正可检测的。要进行猜测,您可以使用我在回答中建议的工具之一显然cchardet
更快,但需要cython
libmagic
确实是chardet
的可行替代品。关于名为pythonmagic
的独特软件包的详细信息!我是
import subprocess
file = "path/to/file/file.txt"
encoding = subprocess.Popen("file -bi "+file, shell=True, stdout=subprocess.PIPE).stdout
encoding = re.sub(r"(\\n)[^a-z0-9\-]", "", str(encoding.read()).split("=")[1], flags=re.IGNORECASE)
print(encoding)