यूनिकोडडॉफॉर्सेट: 'utf8' कोडेक 0x9c बाइट को डिकोड नहीं कर सकता है


289

मेरे पास एक सॉकेट सर्वर है जिसे क्लाइंट से UTF-8 वैध वर्ण प्राप्त करना है।

समस्या कुछ क्लाइंट्स (मुख्य रूप से हैकर्स) के ऊपर गलत डेटा भेजने की है।

मैं आसानी से वास्तविक ग्राहक को अलग कर सकता हूं, लेकिन मैं भेजे गए सभी डेटा को फाइलों में लॉग कर रहा हूं ताकि बाद में इसका विश्लेषण कर सकूं।

कभी-कभी मुझे ऐसे पात्र मिलते œहैं जो UnicodeDecodeErrorत्रुटि का कारण बनते हैं ।

मुझे उन वर्णों के साथ या उसके बिना स्ट्रिंग UTF-8 बनाने में सक्षम होने की आवश्यकता है।


अपडेट करें:

मेरे विशेष मामले के लिए सॉकेट सेवा एक एमटीए थी और इस प्रकार मुझे केवल ASCII कमांड प्राप्त करने की उम्मीद है जैसे:

EHLO example.com
MAIL FROM: <john.doe@example.com>
...

मैं JSON में यह सब लॉग कर रहा था।

तब कुछ लोगों ने अच्छे इरादों के बिना सभी प्रकार के कबाड़ को बेचने का फैसला किया।

यही कारण है कि मेरे विशिष्ट मामले के लिए गैर ASCII वर्णों को छीनना पूरी तरह से ठीक है।


1
क्या स्ट्रिंग किसी फाइल या सॉकेट से बाहर आती है? क्या आप सॉकेट / फ़ाइलहैंडलर के माध्यम से भेजने से पहले स्ट्रिंग को एन्कोडेड एन्कोडेड डिकोड के उदाहरणों को पोस्ट कर सकते हैं?
देवसंड

क्या मैंने लिखा या मैंने नहीं लिखा कि स्ट्रिंग सॉकेट के ऊपर आती है? मैंने बस सॉकेट से स्ट्रिंग को पढ़ा और इसे एक शब्दकोष में डाल दिया और फिर JSON इसे साथ भेजने के लिए। उन वर्णों के कारण JSON फ़ंक्शन विफल हो गया।
ट्रांसविलवल्द

क्या आप समस्या का अपना नमूना डेटा डाल सकते हैं
शुभम शर्मा

जवाबों:


343

http://docs.python.org/howto/unicode.html#the-unicode-type

str = unicode(str, errors='replace')

या

str = unicode(str, errors='ignore')

नोट: यह प्रश्न को अक्षर को अनदेखा करेगा (अनदेखा) उनके बिना स्ट्रिंग लौटाएगा।

मेरे लिए यह आदर्श मामला है क्योंकि मैं इसे गैर-एएससीआईआई इनपुट के खिलाफ संरक्षण के रूप में उपयोग कर रहा हूं जो मेरे आवेदन की अनुमति नहीं है।

वैकल्पिक रूप से:codecs फ़ाइल में पढ़ने के लिए मॉड्यूल से खुली विधि का उपयोग करें :

import codecs
with codecs.open(file_name, 'r', encoding='utf-8',
                 errors='ignore') as fdata:

45
हां, हालांकि यह आमतौर पर बुरा व्यवहार / खतरनाक है, क्योंकि आप केवल पात्रों को खो देंगे। इनपुट स्ट्रिंग की एन्कोडिंग का निर्धारण या पता लगाने के लिए बेहतर है और इसे पहले यूनिकोड में डिकोड करें, फिर UTF-8 के रूप में एनकोड करें, उदाहरण के लिए:str.decode('cp1252').encode('utf-8')
बेन होयट

कुछ मामलों में हाँ आप सही हैं इससे समस्याएँ हो सकती हैं। मेरे मामले में मुझे उनकी परवाह नहीं है क्योंकि वे मेरे सॉकेट सर्वर से जुड़ने वाले क्लाइंट के खराब फॉर्मेटिंग और प्रोग्रामिंग से उत्पन्न होने वाले अतिरिक्त अक्षर लगते हैं।
ट्रांसविलवड

यह वास्तव में मदद करता है अगर स्ट्रिंग की सामग्री वास्तव में अमान्य है, मेरे मामले में '\xc0msterdam'जो u'\ufffdmsterdam'
बदले में

3
यदि आप यहां समाप्त हो गए क्योंकि आपको फ़ाइल पढ़ने में समस्या हो रही है, तो फ़ाइल को बाइनरी मोड में खोलने से मदद मिल सकती है: open(file_name, "rb")और फिर ऊपर की टिप्पणियों से बेन के दृष्टिकोण को लागू करें
क्रिश्चियन

एक ही विकल्प और भी अधिक के लिए लागू होता है, उदाहरण के लिए "something.decode ()"
अलेक्जेंडर स्टोह

83

सी से पायथन में इंजन को बदलते हुए मेरे लिए चाल चली।

इंजन सी है:

pd.read_csv(gdp_path, sep='\t', engine='c')

'utf-8' कोडेक बाइट 0x92 को 18 की स्थिति में डिकोड नहीं कर सकता: अमान्य प्रारंभ बाइट

इंजन पायथन है:

pd.read_csv(gdp_path, sep='\t', engine='python')

मेरे लिए कोई त्रुटि नहीं।


3
यह वास्तव में एक अच्छा समाधान है। मुझे नहीं पता कि इसे क्यों अस्वीकृत किया गया था।
ℕʘʘḆḽḘ

यदि आपके पास बहुत बड़ी csvफ़ाइल है तो यह एक अच्छा विचार नहीं हो सकता है । यह आपको एक OutOfMemoryत्रुटि या आपके नोटबुक के कर्नेल के एक स्वचालित पुनरारंभ के लिए ले जा सकता है । आपको encodingइस मामले पर सेट करना चाहिए ।
लुकासब्र

1
बहुत बढ़िया जवाब। धन्यवाद। इसने मेरे लिए काम किया। मेरे पास "?" एक हीरे के आकार के चरित्र के अंदर जो समस्या पैदा कर रहा था। सादे आँखों से मैंने "" जो इंच का है। मैंने 2 बातें कीं। a) df = pd.read_csv ('test.csv', n_rows = 10000)। यह इंजन के बिना पूरी तरह से काम करता था। इसलिए मैंने n_rows को यह पता लगाने के लिए बढ़ाया कि किस पंक्ति में त्रुटि थी। b) df = pd.read_csv ('test.csv', इंजन = 'पायथन')। यह काम किया और मैंने df.iloc [36145] का उपयोग करते हुए त्रुटिपूर्ण पंक्ति को मुद्रित किया, इसने मुझे गलत रिकॉर्ड को मुद्रित किया।
जगन्नाथ बनर्जी

1
इसने मेरे लिए भी काम किया ... यकीन नहीं हो रहा कि 'हुड के नीचे' क्या हो रहा है और अगर यह वास्तव में सभी मामलों में एक अच्छा / अच्छा / उचित समाधान है, लेकिन इसने मेरे लिए चाल
चली

1
महान समाधान! बहुत बहुत धन्यवाद।
Pechi

62

इस तरह की समस्याएँ मेरे लिए अब फसलें हैं जिन्हें मैं पायथन 3 में ले गया हूँ। मुझे नहीं पता था कि पायथन 2 बस फ़ाइल एन्कोडिंग के साथ किसी भी मुद्दे को रोल कर रहा था।

मुझे मतभेदों की यह अच्छी व्याख्या मिली और उपरोक्त में से किसी ने भी मेरे लिए काम करने के बाद इसका समाधान कैसे खोजा।

http://python-notes.curiousefficiency.org/en/latest/python3/text_file_processing.html

संक्षेप में, पायथन 3 को पायथन 2 के उपयोग के समान व्यवहार करना संभव बनाने के लिए:

with open(filename, encoding="latin-1") as datafile:
    # work on datafile here

हालांकि, लेख पढ़ें, कोई भी एक आकार सभी समाधान फिट नहीं है।


29
>>> '\x9c'.decode('cp1252')
u'\u0153'
>>> print '\x9c'.decode('cp1252')
œ

16
मैं उलझन में हूँ, आपने cp1252 कैसे चुना? यह मेरे लिए काम किया, लेकिन क्यों? मुझे नहीं पता और अब मैं हार गया हूं: /। क्या आप विस्तृत कर सकते हैं? आपका बहुत बहुत धन्यवाद ! :)
सिरिल एन।

4
क्या आप एक विकल्प प्रस्तुत कर सकते हैं जो सभी पात्रों के लिए काम करता है? क्या उन वर्णों का पता लगाने का एक तरीका है, जिन्हें डिकोड करने की आवश्यकता है ताकि अधिक सामान्य कोड लागू किया जा सके? मैं देख रहा हूँ कि बहुत से लोग इसे देख रहे हैं और मैं कुछ त्यागने के लिए शर्त लगा रहा हूँ, यह मेरे लिए जैसा वांछित विकल्प नहीं है।
ट्रांसिलवल्द

जैसा कि आप देख सकते हैं इस सवाल की लोकप्रियता काफी है। लगता है कि आप अधिक सामान्य समाधान के साथ अपने उत्तर का विस्तार कर सकते हैं?
ट्रांसिलवैलड

13
"एन्कोडिंग रूलेट का अनुमान" के लिए कोई और अधिक सामान्य समाधान नहीं है
पिल्ला

5
यह वेब खोज, भाग्य और अंतर्ज्ञान का एक संयोजन का उपयोग कर पाया: cp1252 थाused by default in the legacy components of Microsoft Windows in English and some other Western languages
bolov

24

मेरे साथ भी यही समस्या थी UnicodeDecodeErrorऔर मैंने इसे इस लाइन के साथ हल किया। पता नहीं अगर सबसे अच्छा तरीका है, लेकिन यह मेरे लिए काम किया।

str = str.decode('unicode_escape').encode('utf-8')

13

पहले, फाइल के प्रकार को पाने के लिए get_encoding_type का उपयोग करना

import os    
from chardet import detect

# get file encoding type
def get_encoding_type(file):
    with open(file, 'rb') as f:
        rawdata = f.read()
    return detect(rawdata)['encoding']

दूसरा, प्रकार के साथ फाइल खोलना:

open(current_file, 'r', encoding = get_encoding_type, errors='ignore')

1
क्या होता है जब यह कोई नहीं
लौटता है

3

किसी के मामले में बस यही समस्या है। YouCompleteMe के साथ विम का उपयोग कर रहा हूँ, इस त्रुटि संदेश के साथ ycmd शुरू करने में विफल रहा, मैंने क्या किया है: export LC_CTYPE="en_US.UTF-8"समस्या दूर हो गई है।


2
यह इस प्रश्न से कैसे संबंधित है?
ट्रांसविल्लाद

1
बिल्कुल वैसा ही, यदि आप जानते हैं कि आप कैसे काम करते हैं। Ycm प्लगइन सॉकेट आर्किटेक्चर है, क्लाइंट और सर्वर के बीच संचार सॉकेट का उपयोग कर रहा है, दोनों ही अजगर मॉड्यूल हैं, पैकेट को डिकोड करने में सक्षम नहीं हैं यदि एन्कोडिंग सेटिंग गलत है
वर्कप्लेलिफ़ेकल

मेरी भी यही समस्या है। क्या आप कृपया मुझे बता सकते हैं कि कहां रखा जाए export LC_CTYPE="en_US.UTF-8"?
रेमन

@ रमन हाय, तुम्हें पता है कि हमारे पास बैश के लिए प्रोफाइल फाइल है? अंदर डालो।
workplaylifecycle

@ हाइलपो, मैं एक विंडोज़ सिस्टम पर हूं :)
रेमन

3

यदि आपको किसी फ़ाइल में परिवर्तन करने की आवश्यकता है, तो आप क्या कर सकते हैं, लेकिन फ़ाइल के एन्कोडिंग को नहीं जानते हैं? यदि आप जानते हैं कि एन्कोडिंग ASCII- संगत है और केवल ASCII भागों को जांचना या संशोधित करना चाहता है, तो आप फ़ाइल को surrogateescape त्रुटि हैंडलर से खोल सकते हैं:

with open(fname, 'r', encoding="ascii", errors="surrogateescape") as f:
    data = f.read()

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.