Имам дълъг списък с имена на домейни, от които трябва да генерирам някои доклади. Списъкът съдържа някои IDN домейни и въпреки че знам как да ги конвертирам в python в командния ред:
>>> domain = u"pfarmerü.com"
>>> domain
u"pfarmerxfc.com"
>>> domain.encode("idna")
"xn--pfarmer-t2a.com"
>>>
Аз се боря да го накарам да работи с малък скрипт, който чете данни от текстовия файл.
#!/usr/bin/python
import sys
infile = open(sys.argv[1])
for line in infile:
print line,
domain = unicode(line.strip())
print type(domain)
print "IDN:", domain.encode("idna")
print
Получавам следния резултат:
$ ./idn.py ./test
pfarmer.com
<type "unicode">
IDN: pfarmer.com
pfarmerü.com
Traceback (most recent call last):
File "./idn.py", line 9, in <module>
domain = unicode(line.strip())
UnicodeDecodeError: "ascii" codec can"t decode byte 0xfc in position 7: ordinal not in range(128)
Аз също се опитах:
#!/usr/bin/python
import sys
import codecs
infile = codecs.open(sys.argv[1], "r", "utf8")
for line in infile:
print line,
domain = line.strip()
print type(domain)
print "IDN:", domain.encode("idna")
print
Което ми даде:
$ ./idn.py ./test
Traceback (most recent call last):
File "./idn.py", line 8, in <module>
for line in infile:
File "/usr/lib/python2.6/codecs.py", line 679, in next
return self.reader.next()
File "/usr/lib/python2.6/codecs.py", line 610, in next
line = self.readline()
File "/usr/lib/python2.6/codecs.py", line 525, in readline
data = self.read(readsize, firstline=True)
File "/usr/lib/python2.6/codecs.py", line 472, in read
newchars, decodedbytes = self.decode(data, self.errors)
UnicodeDecodeError: "utf8" codec can"t decode bytes in position 0-5: unsupported Unicode code range
Тук е моят файл с тестови данни:
pfarmer.com
pfarmerü.com
Много съм наясно с моята нужда сега да разбирам Unicode.
Благодаря,
Петър
Отговори:
13 за отговор № 1трябва да знаете в коя кодировка сте запазили файла. Това ще бъде нещо като "utf-8" (което не е Unicode) или "iso-8859-1" или "cp1252" или подобни.
Тогава можете да направите (ако приемете "utf-8"):
infile = open(sys.argv[1])
for line in infile:
print line,
domain = line.strip().decode("utf-8")
print type(domain)
print "IDN:", domain.encode("idna")
print
Конвертиране на кодирани низове в unicode с decode
, Конвертирайте unicode с низ encode
, Ако се опитате да кодирате нещо, което вече е кодирано, python се опитва да декодира първо, с кодека по подразбиране "ascii", който не работи за ASCII-стойности.
2 за отговор № 2
Първият ви пример е добър, с изключение на:
domain = unicode(line.strip())
тук трябва да посочите конкретно кодиране: unicode(line.strip(), "utf-8")
, В противен случай получавате кодиране по подразбиране, което за безопасност е 7-битов ASCII, откъдето и грешката. Като алтернатива можете да го напишете line.strip().decode("utf-8")
както в примера на knitti, няма разлика в поведението между двата синтаксиса.
Въпреки това, съдейки по грешката "не може да декодира байт 0xfc", мисля, че всъщност не сте запазили test
файл като utf-8. Вероятно затова вторият пример, който също изглежда добре по принцип, не успява.
Вместо това е ISO-8859-1 или много подобенКодова страница на Windows 1252. Ако тя идва от текстов редактор в западната кутия на Windows, то със сигурност ще бъде последната; Linux машини използват utf-8 по подразбиране вместо сега. прочетете файла, като използвате кодирането "cp1252"
вместо.