GBK中的Unicode编码
小弟最近使用Python处理一批新闻语料,主要的工作就是将 <content> 和 <contenttitle> 标签中文本取出,并以空格分割字符。文件中的部分格式如下: </contenttitle> </content>
<doc>
<url>http://sports.sina.com.cn/euro2008/video/601/2008-06-06/105.html</url>
<docno>005e46d7ec87bc5b-63207783d4cca6e0</docno>
<contenttitle>视频-揭幕战捷克即将亮相 “东欧铁骑”信心十足</contenttitle>
<content>评论:1北京时间6月4日,捷克国家足球队离开奥地利的因斯布鲁克训练基地,赶赴瑞士准备与东道主的揭幕战。以上是相关视频报道。</content>
</doc>
细心的朋友或许注意到
北京
前面有个乱码
,此外数字
1
、
6
和
4
都是全角的。全角转半角在
unicode
下容易,但若文件本身是非
unicode
编码(比如gbk),就需要先转码。但即使使用正确的解码器,还是无法对文件进行正确地解码,读取第一行就出错了:
>>> news_file.readline()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'gbk' codec can't decode byte 0xbf in position 2: illegal multibyte sequence
有些转义字符在gbk编码中出现,也会出现编解码错误的情况:
>>> s = "组图:震前汶川风光震前汶川风光 QQ群4914667.作者肚螂皮"
>>> s
'组图:震前汶川风光\ue40c震前汶川风光\u3000QQ群4914667.作者肚螂皮'
>>> news_file = open("D:/news_test.txt", "w")
>>> news_file.write(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'gbk' codec can't encode character '\ue40c' in position 9: illegal multibyte sequence
>>>
我试过在
open
函数中使用
errors="ignore"
,错误是没有了,但这样读取之前
<content>
中的文本会产生乱码。
</content>
>>> news_file.readline()
'<content>组图:震前汶川风光U鹎般氪ǚ绻狻。眩讶海矗梗保矗叮叮罚作者肚螂皮</content>\n'
请问处理上述两种异常情况下并正确地读写文件?有没有开源包能够处理上述问题?
真希波.玛丽
10 years, 10 months ago
Answers
>>> '组图:震前汶川风光\ue40c震前汶川风光\u3000QQ群4914667.作者肚螂皮'.encode('gbk')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'gbk' codec can't encode character '\ue40c' in position 9: illegal multibyte sequence
>>> '组图:震前汶川风光\ue40c震前汶川风光\u3000QQ群4914667.作者肚螂皮'.encode('gb18030')
b'\xd7\xe9\xcd\xbc\xa3\xba\xd5\xf0\xc7\xb0\xe3\xeb\xb4\xa8\xb7\xe7\xb9\xe2\xfd\xa3\xd5\xf0\xc7\xb0\xe3\xeb\xb4\xa8\xb7\xe7\xb9\xe2\xa1\xa1\xa3\xd1\xa3\xd1\xc8\xba\xa3\xb4\xa3\xb9\xa3\xb1\xa3\xb4\xa3\xb6\xa3\xb6\xa3\xb7\xa3\xae\xd7\xf7\xd5\xdf\xb6\xc7\xf2\xeb\xc6\xa4'
>>> '组图:震前汶川风光\ue40c震前汶川风光\u3000QQ群4914667.作者肚螂皮'.encode('gbk', errors='replace').decode('gbk')
'组图:震前汶川风光?震前汶川风光\u3000QQ群4914667.作者肚螂皮'
- 你列举的两个问题用 GB18030 编码就没问题了;
- GB* 编码本来容错就不好,所以遇到无法转换的编码应当用其它字符替代而不是简单地忽略,以免造成后续字符乱码(DOS 时代「删除半个汉字」造成乱码就是因为这个)。
我用 GB18030 解码你的文件没有问题:
Python 3.3.3 (default, Nov 26 2013, 13:33:18)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> d = open('news_test.xml', encoding='gb18030')
>>> c = d.read()
>>>
Python 2.7.6 (default, Nov 26 2013, 12:52:49)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> d = open('news_test.xml')
>>> b = d.read()
>>> c = b.decode('gb18030')
>>>
starway
answered 10 years, 10 months ago