Convertir nombres de dominio a idn en python

Tengo una larga lista de nombres de dominio que necesito para generar algunos informes. La lista contiene algunos dominios IDN, y aunque sé cómo convertirlos en python en la línea de comandos:

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

Estoy luchando para que funcione con un pequeño script que lee datos del archivo de texto.

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

Me sale el siguiente resultado:

 $ ./idn.py ./test pfarmer.com  IDN: pfarmer.com pfarmerü.com Traceback (most recent call last): File "./idn.py", line 9, in  domain = unicode(line.strip()) UnicodeDecodeError: 'ascii' codec can't decode byte 0xfc in position 7: ordinal not in range(128) 

También he intentado:

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

Lo que me dio:

 $ ./idn.py ./test Traceback (most recent call last): File "./idn.py", line 8, in  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 

Aquí está mi archivo de datos de prueba:

 pfarmer.com pfarmerü.com 

Estoy muy consciente de mi necesidad de entender Unicode ahora.

Gracias,

Peter

necesita saber en qué encoding se guardó el archivo. Esto sería algo así como ‘utf-8’ (que NO es Unicode) o ‘iso-8859-1’ o ‘cp1252’ o similar.

Entonces puedes hacer (asumiendo ‘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 

Convierte cadenas codificadas a Unicode con decode . Convertir unicode a cadena con encode . Si intenta codificar algo que ya está codificado, Python intenta decodificar primero, con el códec predeterminado ‘ascii’ que falla para valores que no son ASCII.

Tu primer ejemplo está bien, excepto que:

 domain = unicode(line.strip()) 

tienes que especificar una encoding particular aquí: unicode(line.strip(), 'utf-8') . De lo contrario, obtendrá la encoding predeterminada, que por seguridad es ASCII de 7 bits, por lo tanto, el error. Alternativamente, puedes deletrearlo line.strip().decode('utf-8') como en el ejemplo de knitti; No hay diferencia en el comportamiento entre las dos syntax.

Sin embargo, a juzgar por el error “no se puede decodificar el byte 0xfc”, creo que no ha guardado su archivo de test como UTF-8. Es de suponer que esta es la razón por la que el segundo ejemplo, que también parece correcto en principio, falla.

En su lugar, es ISO-8859-1 o la página de códigos de Windows 1252 muy similar. Si proviene de un editor de texto en una caja de Windows occidental, seguramente será la última; Las máquinas Linux usan UTF-8 por defecto en lugar de hoy en día. Asegúrate de guardar tu archivo como UTF-8 o lee el archivo usando la encoding 'cp1252' lugar.