/ / Konwertowanie nazw domen na idn w python - python, unicode

Konwersja nazw domen na idn w python - python, unicode

Mam długą listę nazw domen, na których muszę generować raporty. Lista zawiera kilka domen IDN i chociaż wiem, jak je przekonwertować w Pythonie w wierszu poleceń:

>>> domain = u"pfarmerü.com"
>>> domain
u"pfarmerxfc.com"
>>> domain.encode("idna")
"xn--pfarmer-t2a.com"
>>>

Staram się, aby działał z małym skryptem odczytującym dane z pliku tekstowego.

#!/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

Otrzymuję następujące wyniki:

$ ./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)

Próbowałem również:

#!/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

Co dało mi:

$ ./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

Oto mój plik danych testowych:

pfarmer.com
pfarmerü.com

Jestem bardzo świadomy mojej potrzeby zrozumienia Unicode teraz.

Dzięki,

Piotr

Odpowiedzi:

13 dla odpowiedzi nr 1

musisz wiedzieć, w którym kodowaniu zapisałeś plik. Byłoby to coś w rodzaju „utf-8” (który NIE jest Unicode) lub „iso-8859-1” lub „cp1252” lub podobnie.

Wtedy możesz to zrobić (zakładając „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

Konwertuj zakodowane ciągi znaków na unicode decode. Konwertuj Unicode na ciąg znaków encode. Jeśli spróbujesz zakodować coś, co jest już zakodowane, python próbuje najpierw zdekodować, z domyślnym kodekiem „ascii”, który nie działa dla wartości innych niż ASCII.


2 dla odpowiedzi nr 2

Twój pierwszy przykład jest w porządku, z wyjątkiem:

domain = unicode(line.strip())

musisz tutaj podać konkretne kodowanie: unicode(line.strip(), "utf-8"). W przeciwnym razie otrzymasz domyślne kodowanie, które dla bezpieczeństwa jest 7-bitowe ASCII, stąd błąd. Alternatywnie możesz to przeliterować line.strip().decode("utf-8") jak w przykładzie knitti, nie ma różnicy w zachowaniu między dwiema składniami.

Jednak sądząc po błędzie „nie można„ dekodować bajtu 0xfc ”, myślę, że właściwie nie zapisałeś swojego test plik jako utf-8. Przypuszczalnie dlatego drugi przykład, który zasadniczo również wygląda dobrze, zawodzi.

Zamiast tego jest ISO-8859-1 lub bardzo podobnyStrona kodowa Windows 1252. Jeśli pochodzi z edytora tekstowego w oknie Western Windows, z pewnością będzie to druga; maszyny Linux używają teraz domyślnie utf-8. Upewnij się, że zapisałeś plik jako utf-8 lub przeczytaj plik za pomocą kodowania "cp1252" zamiast.