我正在使用Python 2.6.1开发Windows。
我有一个包含单个字符串Hello的Unicode UTF-16文本文件,如果我在二进制编辑器中看到它,我看到:
FF FE 48 00 65 00 6C 00 6C 00 6F 00 0D 00 0A 00
BOM H e l l o CR LF
我想要做的是阅读此文件,通过Google Translate API运行,并将其和结果写入新的Unicode UTF-16文本文件。
我编写了以下Python脚本(实际上我写了一些比这更复杂的东西,有更多的错误检查,但这被删除作为一个最小的测试用例):
#!/usr/bin/python
import urllib
import urllib2
import sys
import codecs
def translate(key, line, lang):
ret = ""
print "translating " + line.strip() + " into " + lang
url = "https://www.googleapis.com/language/translate/v2?key=" + key + "&source=en&target=" + lang + "&q=" + urllib.quote(line.strip())
f = urllib2.urlopen(url)
for l in f.readlines():
if l.find("translatedText") > 0 and l.find('""') == -1:
a,b = l.split(":")
ret = unicode(b.strip('"'), encoding='utf-16', errors='ignore')
break
return ret
rd_file_name = sys.argv[1]
rd_file = codecs.open(rd_file_name, encoding='utf-16', mode="r")
rd_file_new = codecs.open(rd_file_name+".new", encoding='utf-16', mode="w")
key_file = open("api.key","r")
key = key_file.readline().strip()
for line in rd_file.readlines():
new_line = translate(key, line, "ja")
rd_file_new.write(unicode(line) + "\n")
rd_file_new.write(new_line)
rd_file_new.write("\n")
这给了我一个几乎是Unicode的文件,其中包含一些额外的字节:
FF FE 48 00 65 00 6C 00 6C 00 6F 00 0D 00 0A 00 0A 00
20 22 E3 81 93 E3 82 93 E3 81 AB E3 81 A1 E3 81 AF 22 0A 00
我可以看到20是空格,22是引号,我假设“E3”是urllib2用于表示下一个字符是UTF-16编码的转义字符?
如果我运行相同的脚本,但用“cs”(捷克语)而不是“ja”(日语)作为目标语言,响应都是ASCII,我首先得到带有“Hello”的Unicode文件作为UTF- 16个字符,然后“Ahoj”作为单字节ASCII字符。
我确定我错过了一些明显的东西,但我看不清楚是什么。我对查询的结果尝试了urllib.unquote(),但没有帮助。我也尝试打印字符串,因为它返回f.readlines()并且它看起来很合理,但很难分辨,因为我的终端窗口不能正确支持Unicode。
还有其他任何建议吗?我看过建议的傻瓜,但它们似乎都不符合我的情况。
答案 0 :(得分:5)
我相信Google的输出是UTF-8,而不是UTF-16。试试这个修复:
ret = unicode(b.strip('"'), encoding='utf-8', errors='ignore')
答案 1 :(得分:2)
那些E3字节不是“转义字符”。如果一个人无法访问文档,并且被迫做出猜测,那么对响应编码最可能的怀疑就是UTF-8。期望(根据日本的一周假期):像“konnichiwa”。
>>> response = "\xE3\x81\x93\xE3\x82\x93\xE3\x81\xAB\xE3\x81\xA1\xE3\x81\xAF"
>>> ucode = response.decode('utf8')
>>> print repr(ucode)
u'\u3053\u3093\u306b\u3061\u306f'
>>> import unicodedata
>>> for c in ucode:
... print unicodedata.name(c)
...
HIRAGANA LETTER KO
HIRAGANA LETTER N
HIRAGANA LETTER NI
HIRAGANA LETTER TI
HIRAGANA LETTER HA
>>>
看起来跟我足够近......