2010-09-21 9 views
5

Ho una lunga lista di nomi di dominio su cui ho bisogno di generare alcuni rapporti. L'elenco contiene alcuni domini IDN, e anche se so come convertire loro in pitone sulla riga di comando:Conversione di nomi di dominio in idn in python

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

sto lottando per farlo funzionare con un piccolo script che legge i dati dal file di testo.

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

ottengo il seguente output:

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

Ho anche provato:

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

che mi ha dato:

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

Ecco il mio file di dati di test:

pfarmer.com 
pfarmerü.com 

Sono molto consapevole del mio bisogno di capire unicode ora.

Grazie,

Peter

risposta

13

avete bisogno di sapere in cui la codifica si file è stato salvato. Questo sarebbe qualcosa come "utf-8" (che NON è Unicode) o "iso-8859-1" o "cp1252" o simili.

Poi si può fare (supponendo '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 

Converti codificato stringhe Unicode con decode. Converti unicode in stringa con encode. Se provi a codificare qualcosa che è già codificato, python prova a decodificare per primo, con il codec di default 'ascii' che fallisce per valori non ASCII.

2

Il tuo primo esempio è bene, tranne che:

domain = unicode(line.strip()) 

è necessario specificare una particolare codifica qui: unicode(line.strip(), 'utf-8'). Altrimenti si ottiene la codifica predefinita che per sicurezza è ASCII a 7 bit, quindi l'errore. In alternativa puoi scrivere lo line.strip().decode('utf-8') come nell'esempio di knitti; non c'è differenza di comportamento tra le due sintassi.

Tuttavia, a giudicare dall'errore "Impossibile decodificare il byte 0xfc", penso che tu non abbia effettivamente salvato il tuo file test come UTF-8. Presumibilmente questo è il motivo per cui il secondo esempio, che in linea di principio sembra OK, fallisce.

Invece è ISO-8859-1 o la stessa tabella codici di Windows 1252. Se proviene da un editor di testo su una scatola di Windows occidentale, sarà sicuramente quest'ultima; Al giorno d'oggi, le macchine Linux usano UTF-8 per impostazione predefinita. Assicurati di salvare il tuo file come UTF-8 o leggi il file usando la codifica 'cp1252'.

Problemi correlati