ইউনিকোড ডিকোড এরিয়ার: 'utf8' কোডেক বাইট 0x9c ডিকোড করতে পারে না


289

আমার একটি সকেট সার্ভার রয়েছে যা ক্লায়েন্টদের কাছ থেকে ইউটিএফ -8 বৈধ অক্ষর পাওয়ার কথা।

সমস্যাটি হ'ল কিছু ক্লায়েন্ট (প্রধানত হ্যাকার) এর মাধ্যমে সমস্ত ভুল ধরণের ডেটা প্রেরণ করছে।

আমি সহজেই খাঁটি ক্লায়েন্টকে আলাদা করতে পারি, তবে আমি প্রেরিত সমস্ত ডেটা ফাইলগুলিতে লগ করছি যাতে আমি এটি পরে বিশ্লেষণ করতে পারি।

কখনও কখনও আমি এই জাতীয় অক্ষর পাই œযা UnicodeDecodeErrorত্রুটির কারণ হয় ।

আমার এই অক্ষরগুলি দিয়ে বা ছাড়াই UTF-8 স্ট্রিংটি তৈরি করতে সক্ষম হওয়া দরকার।


হালনাগাদ:

আমার বিশেষ ক্ষেত্রে সকেট পরিষেবাটি একটি এমটিএ ছিল এবং সুতরাং আমি কেবল ASCII কমান্ড যেমন প্রত্যাশা করতাম তা প্রত্যাশা করি:

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

আমি জেএসএনে এই সমস্ত লগ করছি।

তারপরে কিছু লোক ভাল উদ্দেশ্য ছাড়াই সমস্ত ধরণের জাঙ্ক বিক্রি করার সিদ্ধান্ত নিয়েছে।

এ কারণেই আমার নির্দিষ্ট কেসটির জন্য এটি ASCII নয় এমন অক্ষরগুলি ছাঁটাই করা পুরোপুরি ঠিক।


1
স্ট্রিংটি কোনও ফাইল বা সকেট থেকে বেরিয়ে আসে? আপনি কি সকেট / ফাইলহ্যান্ডলারের মাধ্যমে প্রেরণের আগে স্ট্রিংটি এনকোড করা শেষের কোড কোড পোস্ট করতে পারেন?
devsnd

আমি কি লিখেছিলাম বা লিখিনি যে সকেটের উপরে স্ট্রিংটি আসে? আমি কেবল সকেট থেকে স্ট্রিংটি পড়ি এবং এটি একটি অভিধানে রাখি এবং তারপরে এটি পাঠাতে জেএসওএন। এই চরিত্রগুলির কারণে JSON ফাংশন ব্যর্থ হয়েছে।
transilvlad

আপনি কি দয়া করে সমস্যার নমুনা ডেটা রাখতে পারেন
শুভ শর্মা

উত্তর:


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
হ্যাঁ, যদিও এটি সাধারণত খারাপ অভ্যাস / বিপজ্জনক, কারণ আপনি কেবল অক্ষরগুলি হারাবেন। ইনপুট স্ট্রিংয়ের এনকোডিং নির্ধারণ করা এবং এটি প্রথমে ইউনিকোডে ডিকোড করা ভাল, তবে ইউটিএফ -8 হিসাবে এনকোড করুন উদাহরণস্বরূপ:str.decode('cp1252').encode('utf-8')
বেন হোয়েট

কিছু ক্ষেত্রে হ্যাঁ আপনি ঠিক বলেছেন এটি সমস্যার কারণ হতে পারে। আমার ক্ষেত্রে আমি তাদের যত্ন নিই না কারণ তারা আমার সকেট সার্ভারে সংযুক্ত ক্লায়েন্টদের খারাপ ফর্ম্যাটিং এবং প্রোগ্রামিং থেকে উত্পন্ন অতিরিক্ত অক্ষর বলে মনে হয়।
transilvlad

এই এক আসলে সাহায্য করে যদি স্ট্রিং এর বিষয়বস্তু আমার ক্ষেত্রে, আসলে অবৈধ '\xc0msterdam'যা করার সক্রিয় u'\ufffdmsterdam'প্রতিস্থাপন
PvdL

3
যদি আপনি এখানেই শেষ হয়ে যান কারণ আপনার কোনও ফাইল পড়তে সমস্যা হচ্ছে, বাইনারি মোডে ফাইলটি খুলতে সাহায্য করতে পারে: open(file_name, "rb")এবং তারপরে উপরের মন্তব্যগুলি থেকে বেনের পদ্ধতির প্রয়োগ করুন
ক্রিশ্চিয়ান

একই বিকল্পটি আরও বেশি ক্ষেত্রে প্রযোজ্য, যেমন "
কিছু.ডেকোড

83

সি থেকে পাইথনে ইঞ্জিন পরিবর্তন করা আমার পক্ষে কৌশলটি করেছে।

ইঞ্জিন সি:

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

'utf-8' কোডেক 18x পজিশনে 0x92 বাইট ডিকোড করতে পারে না: অবৈধ শুরু বাইট

ইঞ্জিনটি পাইথন:

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

আমার জন্য কোন ত্রুটি।


3
এটি আসলে একটি ভাল সমাধান। আমি জানি না কেন এটি হ্রাস করা হয়েছিল।
3

আপনার কাছে বিশাল csvফাইল থাকলে এটি ভাল ধারণা হতে পারে না । এটি আপনাকে একটি OutOfMemoryত্রুটি বা আপনার নোটবুকের কার্নেলটি স্বয়ংক্রিয়ভাবে পুনঃসূচনা করতে পারে । আপনি encodingএই ক্ষেত্রে সেট করা উচিত ।
লুকাসবিআর

1
দুর্দান্ত উত্তর। ধন্যবাদ. এটি আমার পক্ষে কাজ করেছে। আমার কাছে "?" একটি হীরা আকারের চরিত্রের ভিতরে ছিল যা সমস্যার কারণ হয়ে দাঁড়িয়েছিল। সরল চোখে আমার '' "ছিল যা ইঞ্চি। আমি 2 জিনিস খুঁজে বের করতে। a) df = pd.read_csv ('test.csv', n_rows = 10000) 100 এটি ইঞ্জিন ছাড়া পুরোপুরি কাজ করে worked সুতরাং কোন সারিটিতে ত্রুটি রয়েছে তা নির্ধারণ করার জন্য আমি n_rows বাড়িয়েছি। খ) ডিএফ = পিডি.ড্রেড_সিএসভি ('test.csv', ইঞ্জিন = 'পাইথন')। এটি কাজ করেছে এবং আমি df.iloc [36145] ব্যবহার করে ভুল করা সারিটি মুদ্রণ করেছি, এটি আমাকে ভুল রেকর্ডটি মুদ্রণ করেছে।
জগন্নাথ ব্যানার্জি

1
এটি আমার পক্ষেও কাজ করেছে ... নিশ্চিত নন যে 'হুডের নীচে' কী ঘটছে এবং যদি এটি প্রকৃতপক্ষে সব ক্ষেত্রেই একটি ভাল / ভাল / যথাযথ সমাধান হয় তবে এটি আমার পক্ষে কৌশলটি করেছে;)
ক্রিসভডবার্গ

1
দুর্দান্ত সমাধান! তোমাকে অনেক ধন্যবাদ.
পেচি

62

এই ধরণের ইস্যুটি আমার জন্য আপাতত আমি পাইথন 3 এ চলে এসেছি I আমার কোনও ধারণা ছিল না পাইথন 2 কেবলমাত্র ফাইল এনকোডিংয়ের সাথে কোনও সমস্যা বাষ্প ling

আমি পার্থক্যগুলির এই দুর্দান্ত ব্যাখ্যাটি পেয়েছি এবং উপরের কোনওটি আমার পক্ষে কাজ না করার পরে কীভাবে একটি সমাধান খুঁজে পাবে।

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
আমি বিভ্রান্ত, আপনি সিপি 1252 কীভাবে বেছে নিলেন? এটি আমার পক্ষে কাজ করেছিল, তবে কেন? আমি জানি না এবং এখন আমি হারিয়ে গেছি: /। আপনি বিস্তারিত বলতে পারেন? অনেক ধন্যবাদ ! :)
সিরিল এন।

4
আপনি কি এমন একটি বিকল্প উপস্থাপন করতে পারেন যা সমস্ত চরিত্রের জন্য কাজ করে? এমন আরও একটি জেনেরিক কোড প্রয়োগ করা যেতে পারে যাতে ডিকোডিং করা দরকার এমন অক্ষরগুলি সনাক্ত করার কোনও উপায় কি? আমি দেখতে পাচ্ছি যে অনেকে এই দিকে তাকিয়ে আছেন এবং আমি বাজি ধরছি যে কিছুটা ছাড়াই আমার পক্ষে পছন্দসই বিকল্প নয়।
transilvlad

আপনি দেখতে পাচ্ছেন যে এই প্রশ্নটির যথেষ্ট জনপ্রিয়তা রয়েছে। আপনি আরও সাধারণ সমাধান সহ আপনার উত্তর প্রসারিত করতে পারেন মনে হয়?
transilvlad

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

কারও ক্ষেত্রে একই সমস্যা রয়েছে। আমি ইউকমিউলটাইম এর সাথে উইম ব্যবহার করছি , এই ত্রুটি বার্তাটি দিয়ে ycmd শুরু করতে ব্যর্থ হলাম , আমি যা করেছি তা হল:, export LC_CTYPE="en_US.UTF-8"সমস্যাটি চলে গেছে।


2
এটি এই প্রশ্নের সাথে কীভাবে সম্পর্কিত?
transilvlad

1
হুবহু একই, যদি আপনি জানেন যে আপনি কীভাবে কাজ করেন। ওয়াইসিএম প্লাগইনটি সকেট আর্কিটেকচার, ক্লায়েন্ট এবং সার্ভারের মধ্যে যোগাযোগ সকেট ব্যবহার করছে, উভয়ই পাইথন মডিউল, এনকোডিং সেটিংটি ভুল হলে প্যাকেটগুলি ডিকোড করতে সক্ষম নয়
ওয়ার্কপ্লেফ্লাইসাইকেল

আমি একই সমস্যা আছে। আপনি কি আমাকে বলতে পারেন export LC_CTYPE="en_US.UTF-8"?
রেমান

@ রেমনন হাই, আপনি কি জানেন আমাদের বাশের জন্য প্রোফাইল ফাইল আছে? ভিতরে রাখা.
workplaylifecycle

@ হাইলপো, আমি উইন্ডোজ সিস্টেমে আছি :)
রেমন

3

আপনার যদি কোনও ফাইলে পরিবর্তন দরকার হয় তবে আপনি ফাইলটির এনকোডিং জানেন না তবে আপনি কী করতে পারেন? যদি আপনি জানেন যে এনকোডিংটি ASCII- সামঞ্জস্যপূর্ণ এবং কেবল ASCII অংশগুলি পরীক্ষা বা সংশোধন করতে চান, আপনি সার্গেটেস্কেপ ত্রুটি হ্যান্ডলারের সাহায্যে ফাইলটি খুলতে পারেন:

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.