Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python2.5中解码未知unicoding编码的最佳方法_Python_Html_Unicode_Encoding_Character Encoding - Fatal编程技术网

Python2.5中解码未知unicoding编码的最佳方法

Python2.5中解码未知unicoding编码的最佳方法,python,html,unicode,encoding,character-encoding,Python,Html,Unicode,Encoding,Character Encoding,我把它弄对了吗?无论如何,我正在解析很多html,但我并不总是知道它是什么编码(一个令人惊讶的数字)。下面的代码很容易说明我到目前为止一直在做什么,但我相信有更好的方法。非常感谢您的建议 import logging import codecs from utils.error import Error class UnicodingError(Error): pass # these encodings should be in most likely order to save

我把它弄对了吗?无论如何,我正在解析很多html,但我并不总是知道它是什么编码(一个令人惊讶的数字)。下面的代码很容易说明我到目前为止一直在做什么,但我相信有更好的方法。非常感谢您的建议

import logging
import codecs
from utils.error import Error

class UnicodingError(Error):
    pass

# these encodings should be in most likely order to save time
encodings = [ "ascii", "utf_8", "big5", "big5hkscs", "cp037", "cp424", "cp437", "cp500", "cp737", "cp775", "cp850", "cp852", "cp855", 
    "cp856", "cp857", "cp860", "cp861", "cp862", "cp863", "cp864", "cp865", "cp866", "cp869", "cp874", "cp875", "cp932", "cp949", 
    "cp950", "cp1006", "cp1026", "cp1140", "cp1250", "cp1251", "cp1252", "cp1253", "cp1254", "cp1255", "cp1256", "cp1257", "cp1258", 
    "euc_jp", "euc_jis_2004", "euc_jisx0213", "euc_kr", "gb2312", "gbk", "gb18030", "hz", "iso2022_jp", "iso2022_jp_1", "iso2022_jp_2", 
    "iso2022_jp_2004", "iso2022_jp_3", "iso2022_jp_ext", "iso2022_kr", "latin_1", "iso8859_2", "iso8859_3", "iso8859_4", "iso8859_5", 
    "iso8859_6", "iso8859_7", "iso8859_8", "iso8859_9", "iso8859_10", "iso8859_13", "iso8859_14", "iso8859_15", "johab", "koi8_r", "koi8_u", 
    "mac_cyrillic", "mac_greek", "mac_iceland", "mac_latin2", "mac_roman", "mac_turkish", "ptcp154", "shift_jis", "shift_jis_2004", 
    "shift_jisx0213", "utf_32", "utf_32_be", "utf_32_le", "utf_16", "utf_16_be", "utf_16_le", "utf_7", "utf_8_sig" ]

def unicode(string):
    '''make unicode'''
    for enc in self.encodings:
        try:
            logging.debug("unicoder is trying " + enc + " encoding")
            utf8 = unicode(string, enc)
            logging.info("unicoder is using " + enc + " encoding")
            return utf8
        except UnicodingError:
            if enc == self.encodings[-1]:
                raise UnicodingError("still don't recognise encoding after trying do guess.")

因为您使用的是Python,所以可以尝试一下。这是其中的一部分,您也可能会发现它很有用


顾名思义,
UnicodeAmmit
将尽一切努力从世界上的垃圾中获得合适的unicode。

我解决了同样的问题,发现如果没有关于内容的元数据,就无法确定内容的编码类型。这就是为什么我最终采用了你在这里尝试的方法


对于您所做的工作,我唯一的补充建议是,与其按最可能的顺序排列可能的编码列表,不如按特定性排序。我发现某些字符集是其他字符集的子集,因此如果您选择
utf_8
作为第二选择,您将永远找不到
utf_8
的子集(我认为其中一个韩国字符集使用与utf相同的数字空间)。

有两个用于检测未知编码的通用库:

  • 查德,属于
  • 独角兽
chardet应该是一个港口

可以使用以下正则表达式从字节字符串检测utf8:

import re

utf8_detector = re.compile(r"""^(?:
     [\x09\x0A\x0D\x20-\x7E]            # ASCII
   | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
   |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
   | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
   |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
   |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
   | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
   |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
  )*$""", re.X)
在实践中,如果你在学习英语,我发现以下99.9%的时间都有用:

  • 如果它通过上述正则表达式,则为ascii或utf8
  • 如果它包含来自0x80-0x9f但不包含0xa4的任何字节,则它是Windows-1252
  • 如果它包含0xa4,则假定它是拉丁语-15
  • 否则,假设它是拉丁-1

  • 的确如此
    ascii
    utf-8
    的一个子集,也将正确解码为
    utf-8
    ,因此您可以省略
    ascii
    。8位编码,如
    latin-1
    ,在任何情况下都会被解码成某种东西,因此将其中一种放在最后。自动检测完全不知道您的文本,但如果您至少知道文本所用的语言,则只有很少的选项。这就是为什么编码检测基本上意味着根据字母频率猜测语言。呃,unicode()返回unicode而不是UTF-8。很早就尝试了,但失败了很多。真的!有什么问题?让它工作起来可能比你自己的要容易。“你可能会发现世界上的垃圾”?我将其编码并放在这里有一个问题你粘贴的代码:
    ^(?:\xA4)*$
    如果字符串完全是
    \xA4
    且没有其他字符,那么它将匹配。对于另外两个正则表达式,只需
    re.compile(r'\xA4')
    re.compile(r'[\x80-\xBF]')