2010-08-27 13 views
22

मेरे पास एक एक्सेल स्प्रेडशीट है जिसमें मैं पढ़ रहा हूं जिसमें कुछ £ संकेत हैं।यूनिकोड एन्कोडर त्रुटि: 'ascii' कोडेक चरित्र को एन्कोड नहीं कर सकता है xa3 '

जब मैं xlrd मॉड्यूल का उपयोग करने में इसे पढ़ने के लिए कोशिश मैं निम्नलिखित त्रुटि मिलती है:

x = table.cell_value(row, col) 
x = x.decode("ISO-8859-1") 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3' in position 0: ordinal not in range(128) 

अगर मैं x.encode को यह पुनर्लेखन ('utf-8') यह एक त्रुटि फेंक बंद हो जाता है लेकिन दुर्भाग्य से जब मैं कहीं और डेटा (लैटिन -1 के रूप में) लिखता हूं, तो £ संकेत सभी गड़बड़ हो जाते हैं।

मैं इसे कैसे ठीक कर सकता हूं, और सही ढंग से £ संकेतों को पढ़ सकता हूं?

--- अद्यतन ---

कुछ प्रकार पाठकों सुझाव दिया है कि मैं बिल्कुल भी यह डिकोड करने की जरूरत नहीं है, या मैं बस जब मैं करने की जरूरत है लैटिन -1 करने के लिए इसे सांकेतिक शब्दों में बदलना कर सकते हैं। इसके साथ समस्या यह है कि मुझे डेटा को CSV फ़ाइल में अंततः लिखना होगा, और ऐसा लगता है कि कच्चे तारों पर ऑब्जेक्ट होता है।

मैं सांकेतिक शब्दों में बदलना नहीं है या बिल्कुल भी डेटा को डिकोड, तो ऐसा होता है (के बाद मैं एक सरणी के लिए स्ट्रिंग कहा जाता आइटम जोड़ दिया है):

for item in items: 
    #item = [x.encode('latin-1') for x in item] 
    cleancsv.writerow(item) 
File "clean_up_barnet.py", line 104, in <module> 
cleancsv.writerow(item) 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2022' in position 43: ordinal not in range(128) 

मैं एक ही त्रुटि भले ही मैं लैटिन -1 लाइन को अपूर्ण करें।

+0

क्या आप दो बार 'डीकोड' कर रहे हैं? – katrielalex

+0

मुझे ऐसा नहीं लगता है। पिछली पंक्ति xlrd मॉड्यूल से x = table.cell_value (पंक्ति, col) है, हालांकि - शायद यह कुछ मजेदार कर रहा है? – AP257

उत्तर

9

आपका कोड स्निपेट x.decode कहते हैं, लेकिन आप एक एनकोड त्रुटि हो रही है - x अर्थ यूनिकोड पहले से ही है, इसलिए, करने के लिए "डिकोड" यह, यह पहली बाइट्स के एक स्ट्रिंग में बदल गया होना चाहिए (और है कि जहां है डिफ़ॉल्ट कोडेक ansi आता है और विफल रहता है)। अपने पाठ में तब आप कहते हैं, "अगर मैं x। एन्कोड" को फिर से लिखता हूं ... जो ऐसा लगता है कि आप जानते हैं x यूनिकोड है। और आप मतलब यह क्या कर रहा है कर रही है - - एक यूनिकोड x एन्कोडिंग बाइट्स की एक कोडित स्ट्रिंग प्राप्त करने के लिए, या एक यूनिकोड वस्तु में बाइट्स के एक स्ट्रिंग डिकोडिंग

तो क्या यह तुम क्या कर रहे हैं?

मैं यह दुर्भाग्यपूर्ण है कि आप एक यूनिकोड वस्तु पर एक बाइट स्ट्रिंग पर encode, और decode कॉल कर सकते हैं, क्योंकि मुझे लगता है यह कुछ भी नहीं है, लेकिन इस भ्रम को उपयोगकर्ताओं नेतृत्व करने के लिए लगता है लगता है ... लेकिन कम से कम इस मामले में आप का प्रबंधन करने लगते हैं भ्रम का प्रचार करने के लिए (कम से कम मेरे लिए ;-)। आप एनकोड करने के लिए इसे एक निश्चित कोडेक, उदा एक बाइट स्ट्रिंग पाने के लिए चाहते हो सकता है -

, तो के रूप में यह लगता है, x यूनिकोड है, तो आप कभी नहीं "डिकोड" यह करना चाहते हैं लैटिन -1, अगर है कि आप क्या मैं यूनिकोड के साथ चिपके हुए सलाह है कि अपने स्वयं के आंतरिक उपयोग के लिए कार्यक्रम (आई/ओ प्रयोजनों के कुछ प्रकार के लिए की जरूरत है हर समय है - केवल एनकोड/डीकोड अगर और जब आप पूरी तरह जरूरत, या प्राप्त, इनपुट/आउटपुट उद्देश्यों के लिए कोडित बाइट तार)।

+1

धन्यवाद। मुझे लगता है कि यह यूनिकोड है - लेकिन मुझे इसे CSV फ़ाइल में लिखने के लिए एन्कोड करने की आवश्यकता है। जब मैं इसे लैटिन -1 में एन्कोड करने का प्रयास करता हूं, तो मुझे एक और त्रुटि मिलती है। कृपया उपरोक्त मेरा अपडेट देखें ... – AP257

+1

यह पता लगाया - सीएसवी को लिखने से पहले मुझे जिस पंक्ति की आवश्यकता थी वह आइटम = [x.encode ('mac_roman') आइटम में x के लिए था]। इस जवाब को स्वीकार करते हुए क्योंकि यह मुझे काम करने में मदद करता था - धन्यवाद। – AP257

+0

@ एलेक्स-मार्टेलि मुझे आपकी सलाह [इस सवाल] पर प्राप्त करने में खुशी होगी (http://stackoverflow.com/questions/23013236/how-to-encode-xml-into-esri-shapefiles-using-python)। – JJD

2

xlrd यूनिकोड के साथ काम करता है, तो स्ट्रिंग वापस पहुंचने के लिए एक यूनिकोड स्ट्रिंग है। £ -ign में कोड बिंदु U + 00A3 है, इसलिए कहा गया स्ट्रिंग का प्रतिनिधित्व u'\xa3' होना चाहिए। यह सही ढंग से पढ़ा गया है; यह वह स्ट्रिंग है जिसे आपको अपने पूरे कार्यक्रम के साथ काम करना चाहिए।

जब आप यह (सार, यूनिकोड) स्ट्रिंग कहीं लिखते हैं, आप कोई एन्कोडिंग का चयन करने की जरूरत है।उस बिंदु पर, आपको .encode को उस एन्कोडिंग में होना चाहिए, latin-1 कहें।


>>> book = xlrd.open_workbook("test.xls") 
>>> sh = book.sheet_by_index(0) 
>>> x = sh.cell_value(0, 0) 
>>> x 
u'\xa3' 
>>> print x 
£ 

# sample outputs (for e.g. writing to a file) 
>>> x.encode("latin-1") 
'\xa3' 
>>> x.encode("utf-8") 
'\xc2\xa3' 

# garbage, because x is already Unicode 
>>> x.decode("ascii") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3' in position 0: 
ordinal not in range(128) 
>>> 
+0

कृपया ऊपर मेरा अपडेट देखें: जब मैं इसे एन्कोड करने की कोशिश करता हूं तो मुझे एक त्रुटि मिलती है ... – AP257

10

क्या इसके लायक है के लिए: मैं xlrd के लेखक हूँ।

क्या xlrd यूनिकोड का उत्पादन करता है?
विकल्प 1: xlrd दस्तावेज़ के पहले स्क्रीनफुल के नीचे यूनिकोड अनुभाग पढ़ें: यह मॉड्यूल सभी टेक्स्ट स्ट्रिंग्स को पायथन यूनिकोड ऑब्जेक्ट्स के रूप में प्रस्तुत करता है।
विकल्प 2: print type(text), repr(text)

आप कहते हैं "" "अगर मैं x.encode को यह पुनर्लेखन ('utf-8') यह एक त्रुटि फेंक बंद हो जाता है, लेकिन दुर्भाग्य से जब मैं तो डेटा बाहर कहीं और लिखने (के रूप में लैटिन -1), £ संकेत सभी गड़बड़ हो गए हैं। "" "निश्चित रूप से यदि आप लैटिन 1 की उम्मीद कर रहे डिवाइस पर यूटीएफ -8-एन्कोडेड टेक्स्ट लिखते हैं, तो यह खराब हो जाएगा। आपने क्या उम्मीद की

आप अपने संपादन में कहते हैं: "" मुझे एक ही त्रुटि मिलती है, भले ही मैं लैटिन -1 लाइन को असम्बद्ध करता हूं "। यह बहुत ही असंभव है - अधिक संभावना है कि आपको एक अलग स्रोत लाइन (लेखक पंक्ति के बजाय असम्बद्ध लैटिन 1 लाइन) में थोड़ा अलग त्रुटि (एसीआई कोडेक के बजाय लैटिन 1 कोडेक का उल्लेख करना) मिला है। त्रुटि संदेश पढ़ना ध्यान से समझने में सहायता करता है।

आपकी समस्या यह है कि सामान्य रूप से आपका डेटा लैटिन 1 में एन्कोडेबल नहीं है; बहुत कम असली दुनिया डेटा है। आपका पाउंड साइन लैटिन 1 में एन्कोडेबल है, लेकिन यह आपके सभी गैर-ASCII डेटा नहीं है। समस्याग्रस्त चरित्र यू +2022 बुलेट है जो लैटिन 1 में एन्कोडेबल नहीं है।

यह मदद की है | आप एक बेहतर जल्दी जवाब देने के लिए यदि आप सामने कहा था कि आप मैक ओएस एक्स ... एक सीएसवी-उपयुक्त एन्कोडिंग के लिए हमेशा की तरह संदिग्ध पर काम कर रहे थे मिल cp1252 है (विंडोज़), नहीं mac-roman

+1

"त्रुटि संदेश पढ़ना ध्यान से समझने में सहायता करता है।" सच है जब त्रुटि संदेश गूढ़ नहीं है। शायद आपके कोड में नहीं, लेकिन वहाँ बहुत सारे त्रुटि संदेश हैं जो स्पष्ट रूप से पढ़ने के इरादे से नहीं थे, कम से कम धरती से नहीं – Davos

5
x = x.decode("ISO-8859-1") 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3' in position 0: ordinal not in range(128) 

देखो बारीकी से: आप एक यूनिकोड मिला *** एनकोड *** डिकोड विधि बुला त्रुटि।

इस का कारण यह है कि decode एक बाइट क्रम (str) से एक unicode वस्तु में बदलने का इरादा है है। लेकिन, जैसा कि जॉन ने कहा, xlrd पहले से ही यूनिकोड स्ट्रिंग का उपयोग करता है, इसलिए x पहले से ही unicode ऑब्जेक्ट है।

इस स्थिति में, पायथन 2.x मानता है कि आप मतलब एक str वस्तु को डिकोड करने के, तो यह "काम आते हुए" आप के लिए एक बनाता है। लेकिन unicode को str में बदलने के लिए, इसे एन्कोडिंग की आवश्यकता है, और ASCII चुनता है क्योंकि यह वर्ण एन्कोडिंग का सबसे कम आम संप्रदाय है। आपका कोड को प्रभावी ढंग से के रूप में

x = x.encode('ascii').decode("ISO-8859-1") 

जो विफल रहता है क्योंकि x एक गैर- ASCII वर्ण है व्याख्या की जाती है।

x के बाद से पहले से ही एक unicode वस्तु decode अनावश्यक है,। हालांकि, अब आप समस्या में भाग लेते हैं कि पायथन 2.x csv मॉड्यूल यूनिकोड का समर्थन नहीं करता है। आपको अपने डेटा को str ऑब्जेक्ट्स में कनवर्ट करना होगा।

for item in items: 
    item = [x.encode('latin-1') for x in item] 
    cleancsv.writerow(item) 

यह सही होगा, सिवाय इसके कि आप चरित्र (U + 2022 BULLET) आपके डेटा में है, और लैटिन -1 यह का प्रतिनिधित्व नहीं कर सकते हैं।

  • लिखें x.encode('latin-1', 'ignore') गोली दूर करने के लिए (या अन्य गैर-लैटिन -1 वर्णों): वहाँ इस समस्या को हल कई तरीके हैं।
  • प्रश्नपत्र के साथ बुलेट को प्रतिस्थापित करने के लिए x.encode('latin-1', 'replace') लिखें।
  • गोलियों को लैटिन -1 वर्ण के साथ * या · पर बदलें।
  • में वर्णित एक वर्ण एन्कोडिंग का उपयोग करें जिसमें आपको आवश्यक सभी वर्ण शामिल हैं।

इन दिनों, यूटीएफ -8 व्यापक रूप से समर्थित है, इसलिए टेक्स्ट फ़ाइलों के लिए किसी भी अन्य एन्कोडिंग का उपयोग करने का कोई कारण नहीं है।

19

सभी "'ascii' कोडेक के चारों ओर एक बहुत ही आसान तरीका चरित्र को एन्कोड नहीं कर सकता ..." csvwriter के साथ मुद्दों को csvwriter के लिए ड्रॉप-इन प्रतिस्थापन unicodecsv का उपयोग करना है।

पिप के साथ unicodecsv स्थापित करें और फिर आप ठीक उसी तरह से उपयोग कर सकते हैं, जैसे:

import unicodecsv 
file = open('users.csv', 'w') 
w = unicodecsv.writer(file) 
for user in User.objects.all().values_list('first_name', 'last_name', 'email', 'last_login'): 
    w.writerow(user) 
0

xlrd के साथ कार्य करना, मैं एक पंक्ति में है ... xl_data.find (एसटीआर (CELL_VALUE)) ... जो त्रुटि देता है: "ascii 'कोडेक स्थिति 3 में वर्ण \' xxf 'को एन्कोड नहीं कर सकता है: क्रमशः श्रेणी में नहीं (128)"। मंचों में सभी सुझाव मेरे जर्मन शब्दों के लिए बेकार हैं। लेकिन इसमें बदल रहा है: ... xl_data.find (cell.value) ... कोई त्रुटि नहीं देता है। इसलिए, मुझे लगता है कि xldr के साथ कुछ कमांड में तर्क के रूप में तारों का उपयोग विशिष्ट एन्कोडिंग समस्याएं हैं।

संबंधित मुद्दे

 संबंधित मुद्दे