2010-09-21 4 views
5

में डोमेन नामों को idn में परिवर्तित करना मेरे पास डोमेन नामों की एक लंबी सूची है जिसे मुझे कुछ रिपोर्ट जेनरेट करने की आवश्यकता है। इस सूची में केवल IDN डोमेन हैं, और यद्यपि मैं कैसे कमांड लाइन पर अजगर में उन्हें बदलने के लिए पता है:पाइथन

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

मैं इसे पाठ फ़ाइल से एक छोटे से स्क्रिप्ट को पढ़ने के डेटा के साथ काम करने के लिए प्राप्त करने के लिए संघर्ष कर रहा हूँ।

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

कौन मुझे दिया:

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

मुझे अब यूनिकोड को समझने की मेरी आवश्यकता के बारे में बहुत जानकारी है।

धन्यवाद,

पीटर

उत्तर

13

आप को पता है जो आप एन्कोडिंग फ़ाइल में सहेजा गया था की जरूरत है। यह 'utf-8' (जो यूनिकोड नहीं है) या 'iso-8859-1' या 'cp1252' या समान रूप से कुछ होगा। decode के साथ यूनिकोड को


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 

Convert इनकोडिंग तार:

तो फिर तुम क्या कर सकते हैं (यह मानते हुए 'utf-8')। यूनिकोड को encode के साथ स्ट्रिंग में कनवर्ट करें। यदि आप पहले से एन्कोड किए गए कुछ को एन्कोड करने का प्रयास करते हैं, तो पाइथन डिफ़ॉल्ट कोडेक 'ascii' के साथ पहले डीकोड करने का प्रयास करता है जो गैर-ASCII-values ​​के लिए विफल रहता है।

2

आपका पहला उदाहरण है, ठीक है सिवाय इसके कि:

domain = unicode(line.strip()) 

तुम यहाँ एक विशेष एन्कोडिंग निर्दिष्ट करने के लिए है: unicode(line.strip(), 'utf-8')। अन्यथा आपको डिफ़ॉल्ट एन्कोडिंग मिलती है जो सुरक्षा के लिए 7-बिट ASCII है, इसलिए त्रुटि। वैकल्पिक रूप से आप line.strip().decode('utf-8') को बुनी के उदाहरण के रूप में वर्तनी कर सकते हैं; दो वाक्यविन्यासों के बीच व्यवहार में कोई अंतर नहीं है।

हालांकि त्रुटि से निर्णय "बाइट 0xfc डीकोड नहीं कर सकता", मुझे लगता है कि आपने वास्तव में अपनी test फ़ाइल को यूटीएफ -8 के रूप में सहेजा नहीं है। संभवतः यही कारण है कि दूसरा उदाहरण, जो सैद्धांतिक रूप से ठीक दिखता है, विफल रहता है।

इसके बजाय यह आईएसओ -885 9 -1 या बहुत ही समान विंडोज कोड पेज 1252 है। यदि यह पश्चिमी विंडोज बॉक्स पर एक टेक्स्ट एडिटर से आया है तो यह निश्चित रूप से बाद वाला होगा; लिनक्स मशीनें आजकल डिफ़ॉल्ट रूप से यूटीएफ -8 का उपयोग करती हैं। या तो अपनी फ़ाइल को यूटीएफ -8 के रूप में सहेजना सुनिश्चित करें, या इसके बजाय एन्कोडिंग 'cp1252' का उपयोग करके फ़ाइल को पढ़ें।