2010-09-21 93 views
5

我有一長串需要生成報告的域名。該列表包含了一些IDN域名,雖然我知道如何將它們轉換在python在命令行:在python中將域名轉換爲idn

>>> domain = u"pfarmerü.com" 
>>> domain 
u'pfarmer\xfc.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

你需要知道在你的編碼文件保存。這將是'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 

轉換編碼字符串與decode爲Unicode。將unicode轉換爲與encode的字符串。如果你嘗試對已經編碼的東西進行編碼,python首先嚐試解碼,使用默認編解碼器「ascii」,該編解碼器對非ASCII值失敗。

2

你的第一個例子是好的,但是:

domain = unicode(line.strip()) 

,你必須在這裏指定一個特定的編碼:unicode(line.strip(), 'utf-8')。否則,你會得到默認編碼,這對於安全性來說是7位ASCII,因此是錯誤。或者,你可以像knitti的例子那樣拼寫它line.strip().decode('utf-8');這兩種語法之間的行爲沒有區別。

但是,通過錯誤判斷「無法解碼字節0xfc」,我認爲你實際上並沒有將你的test文件保存爲UTF-8。大概這就是爲什麼第二個例子,原則上看起來不錯的原因,失敗了。

取而代之的是ISO-8859-1或非常類似的Windows代碼頁1252.如果它來自Western Windows盒子上的文本編輯器,它肯定會是後者;現在Linux機器默認使用UTF-8。請確保將文件保存爲UTF-8,或者使用編碼'cp1252'來讀取文件。