python - 无法使用 python 将文本作为 UTF-8 写入文件

标签 python parsing encoding file-io utf-8

我正在开发一个程序,该程序读取下载的网页(存储为“something”.html)并相应地对其进行解析。我在正确编码和解码该程序时遇到一些问题。据我了解,大多数网页都是用 ISO-8859-1 编码的,我检查了此页面的响应,这就是我得到的字符集:

>>> print r.info()
Content-Type: text/html; charset=ISO-8859-1
Connection: close
Cache-Control: no-cache
Date: Sun, 20 Feb 2011 15:16:31 GMT
Server: Apache/2.0.40 (Red Hat Linux)
X-Accel-Cache-Control: no-cache

但是,在页面的元标记中,它声明“utf-8”作为其编码集:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

因此,在 python 中,我尝试了多种方法来读取这些页面、解析它们并写入 utf-8,包括正常读取文件和正常写入:

with open('../results/1.html','r') as f:                                   
    page = f.read()
...
with open('../parsed.txt','w') as f:
    for key in fieldD:
        f.write(key+'\t'+fieldD[key]+'\n')

我尝试明确告诉文件在读写过程中使用哪种编码:

with codecs.open('../results/1.html','r','utf-8') as f:                                
    page = f.read()
...
with codecs.open('../parsed.txt','w','utf-8') as f:                                  
    for key in fieldD:
        f.write(key+'\t'+fieldD[key]+'\n')

明确告诉文件从“iso-8849-1”读取并写入“utf-8”:

with codecs.open('../results/1.html','r','iso_8859_1') as f:
    page = f.read()
...
with codecs.open('../parsed.txt','w','utf-8') as f:                        
    for key in fieldD:
        f.write(key+'\t'+fieldD[key]+'\n')

以及这些想法的所有排列,包括编写为 utf-16、在将每个字符串添加到字典之前对其进行单独编码,以及其他错误的想法。我不确定这里最好的方法是什么。看来我很幸运没有使用任何编码,因为这至少会导致一些文本编辑器正确查看结果(emacs、textwrangler)

我已经阅读了这里有关此主题的几篇文章,但似乎仍然无法弄清楚正在发生的事情。

谢谢。

最佳答案

我遵循了你的指示。显示的页面NOT采用UTF-8编码;使用 UTF-8 解码失败。根据我偶尔使用的一个实验性字符集检测器,它是用基于拉丁语的编码进行编码的...... ISO-8859-1、cp1252 和 ISO-8859-15 之一,并且该语言似乎是 ' es'(西类牙语)或'fr'(法语)。据我看,这是西类牙语。 Firefox(查看 >>> 查看编码)表示它是 ISO-8859-1。

所以现在您需要做的是尝试使用哪些工具可以正确显示您保存的文件。如果找不到,则需要将文件转码为 UTF-8,即 data.decode('ISO-8859-1').encode('UTF-8') 并找到一个显示 UTF-8 的工具正确。不应该太难。 Firefox 可以对我输入的任何编码进行编码并正确显示。

请求“直觉”后更新:

在第三个代码块中,仅包含输入和输出,中间用“...”。输入代码应该生成 unicode 对象,OK。但是在输出代码中,您使用了 str 函数(为什么???)。假设“...”之后仍然有 unicode 对象,如果系统的默认编码是“ascii”(如它应该是)或者默默地破坏你的数据,如果它是'utf8'(因为它不应该是)。请发布(1)“...”的内容(2)import sys; 的结果; print sys.getdefaultencoding() (3) 您在输出文件中“看到”的内容,而不是“Iglesia Católica”中预期的 ó - 是 Ë 吗? (4) 文件中的实际字节(使用 print repr(the data))而不是预期的 ó

已解决您在评论中说您看到Iglesia Cat√ÉØ≥lica ...请注意,显示了四个字符,而不是预期的一个。 这是用 UTF-8 编码两次的症状。下一个难题是显示这些字符的内容,其中两个字符未在 ISO-8859-1 和 cp1252 中映射。我尝试了旧的 DOS 代码页 cp437 和 cp850(仍在 Windows 的命令提示符窗口中使用),但它不适合。 koi8r 也不适合;它需要基于拉丁语的字符集。嗯,宏人呢?田田!! 您已将双重编码的废话发送到 Mac 终端上的标准输出。请参阅下面的演示。

>>> from unicodedata import name
>>> oacute = u"\xf3"
>>> print name(oacute)
LATIN SMALL LETTER O WITH ACUTE
>>> guff = oacute.encode('utf8').decode('latin1').encode('utf8')
>>> guff
'\xc3\x83\xc2\xb3'
>>> for c in guff.decode('macroman'):
...     print name(c)
...
SQUARE ROOT
LATIN CAPITAL LETTER E WITH ACUTE
NOT SIGN
GREATER-THAN OR EQUAL TO
>>>

检查保存的文件 我也将网页保存到一个文件(加上包含 *.jpg、css 文件等的目录)——使用 Firefox“页面另存为”。在您保存的页面上尝试此操作并发布结果。

>>> data = open('g0.htm', 'rb').read()
>>> uc = data.decode('utf8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\python27\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xb7 in position 1130: invalid start byte
>>> pos = data.find("Iglesia Cat")
>>> data[pos:pos+20]
'Iglesia Cat\xf3lica</a>'
>>> # Looks like one of ISO-8859-1 and its cousins to me.

请仔细注意:如果您的文件采用 UTF-8 编码,则使用 UTF-8 编解码器读取该文件将生成 unicode。如果您在解析时没有以某种方式破坏数据,并使用 UTF-8 编解码器写入解析后的 unicode,则它不会被双重编码。您需要仔细查看代码中是否存在“str”(还记得“拼写错误”吗?)、“unicode”、“encode”、“decode”、“utf”、“UTF”等实例。您是否调用了第三个- 方库进行解析?当您在写入输出文件之前 print repr(key), repr(field[key]) 时,您会看到什么?

这变得很乏味。考虑将您的代码和保存的页面放在网络上我们可以查看而不是猜测的地方。

32766.html:我刚刚意识到你就是那个试图将太多文件写入 vfat 文件系统(或类似文件系统)上的文件夹而毁坏了所有 inode 的人。所以你没有进行手动“另存为”。请发布您用于“保存”这些文件的代码。

关于python - 无法使用 python 将文本作为 UTF-8 写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7626044/

相关文章:

python - 如何从kml文件中获取所有坐标?

javascript - 为什么我无法从 POST 请求中获取文件?

python - django模板for循环某些表行仅显示一次

java - 从配置文件解析 Yaml

python - 如何列出 fabfile 中定义的角色?

java - 采用 "not"但不采用 "not like"的词法分析器

c# - C# 中的拆分问题

mysql - 无法将表情符号存储在 utf8mb mysql 表上

c# - 使用 .NET C# MySQL 插入表情符号

javascript - Node.js mikeal/请求模块 - 乱码非 utf8 网站 (Shift_JIS)