2010-09-21 12 views
5

Tengo una larga lista de nombres de dominio sobre los que necesito generar algunos informes. La lista contiene algunos dominios IDN, y aunque sé cómo convertir en pitón en la línea de comandos:Conversión de nombres de dominio a idn en python

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

estoy luchando para conseguir que funcione con un pequeño script de lectura de datos desde el 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 
<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) 

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 <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 

Aquí está mi archivo de datos de prueba:

pfarmer.com 
pfarmerü.com 

Estoy muy consciente de mi necesidad de entender Unicode ahora.

Gracias,

Peter

Respuesta

13

lo que necesita saber en que se codifica el archivo guardado. Esto sería algo así como 'utf-8' (que no es Unicode) o 'iso-8859-1' o 'cp1252' o similar.

A continuación, puede hacer (suponiendo 'UTF-8'):

cadenas

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 codificado a Unicode con decode. Convierta unicode en 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.

2

Su primer ejemplo está muy bien, excepto que:

domain = unicode(line.strip()) 

tiene que especificar una codificación particular aquí: unicode(line.strip(), 'utf-8'). De lo contrario, obtendrá la codificación predeterminada, que por seguridad es ASCII de 7 bits, de ahí el error. Alternativamente, puede deletrearlo line.strip().decode('utf-8') como en el ejemplo de knitti; no hay diferencia en el comportamiento entre las dos sintaxis.

Sin embargo, a juzgar por el error "no se puede decodificar el byte 0xfc", creo que en realidad no ha guardado su archivo test como UTF-8. Presumiblemente, esta es la razón por la cual el segundo ejemplo, que también se ve bien en principio, falla.

En su lugar, es ISO-8859-1 o la página de códigos de Windows muy similar 1252. Si proviene de un editor de texto en un cuadro de Windows occidental, sin duda será el último; Las máquinas Linux usan UTF-8 por defecto en su lugar hoy en día. O bien, asegúrese de guardar su archivo como UTF-8 o lea el archivo usando la codificación 'cp1252'.

Cuestiones relacionadas