পাইথনে ত্রুটি ছাড়াই ইউনিকোডকে ASCII তে রূপান্তর করুন


177

আমার কোডটি কেবল একটি ওয়েব পৃষ্ঠা স্ক্র্যাপ করে, তারপরে এটিকে ইউনিকোডে রূপান্তর করে।

html = urllib.urlopen(link).read()
html.encode("utf8","ignore")
self.response.out.write(html)

তবে আমি একটি পেয়েছি UnicodeDecodeError:


Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/__init__.py", line 507, in __call__
    handler.get(*groups)
  File "/Users/greg/clounce/main.py", line 55, in get
    html.encode("utf8","ignore")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 2818: ordinal not in range(128)

আমি ধরে নিলাম যে এর অর্থ এইচটিএমএল কোথাও কোথাও ইউনিকোডে ভুলভাবে গঠিত প্রচেষ্টা রয়েছে। আমি কি কোনও কোড বাইটগুলি ত্রুটি পাওয়ার পরিবর্তে সমস্যার সৃষ্টি করে তা ফেলে দিতে পারি?


2
গুরুত্বপূর্ণ চরিত্রগুলি বাতিল করা হলে আমি এটিকে ত্রুটি হিসাবে বিবেচনা করি! (এছাড়াও, প্রশ্নটি কোথায়?)
আরাফাঙ্গিয়ন

দেখে মনে হচ্ছে আপনি ওয়েব পৃষ্ঠায় "বিরতিহীন জায়গার" সম্মুখীন হয়েছেন? একটি c2বাইটের আগে করা দরকার বা আপনি সম্ভবত একটি ডিকোড ত্রুটি পেয়েছেন: hexutf8.com/?q=C2A0
জার

উত্তর:


105

2018 আপডেট:

ফেব্রুয়ারী 2018 পর্যন্ত, এর মতো সংকোচনের ব্যবহারগুলি বেশ জনপ্রিয়gzip হয়ে উঠেছে (গুগল, ইউটিউব, ইয়াহু, উইকিপিডিয়া, রেডডিট, স্ট্যাক ওভারফ্লো এবং স্ট্যাক এক্সচেঞ্জ নেটওয়ার্ক সাইটগুলির মতো বৃহত সাইটগুলি সহ, সমস্ত ওয়েবসাইটের প্রায় 73% এটি ব্যবহার করে)।
আপনি যদি গিজপযুক্ত প্রতিক্রিয়া সহ মূল উত্তরের মতো একটি সাধারণ ডিকোড করেন তবে আপনি এর মতো বা অনুরূপ একটি ত্রুটি পাবেন:

ইউনিকোড ডিকোড এরিয়ার: 'utf8' কোডেক 1x8b পজিশনে বাইট ডিকোড করতে পারে না: অপ্রত্যাশিত কোড বাইট

একটি জিপিপিপড প্রতিক্রিয়া ডিকোড করার জন্য আপনাকে নিম্নলিখিত মডিউলগুলি যুক্ত করতে হবে (পাইথন 3 এ):

import gzip
import io

দ্রষ্টব্য: পাইথন 2 এ আপনি এর StringIOপরিবর্তে ব্যবহার করতে চানio

তারপরে আপনি বিষয়বস্তুটিকে এভাবে পার্স করতে পারেন:

response = urlopen("https://example.com/gzipped-ressource")
buffer = io.BytesIO(response.read()) # Use StringIO.StringIO(response.read()) in Python 2
gzipped_file = gzip.GzipFile(fileobj=buffer)
decoded = gzipped_file.read()
content = decoded.decode("utf-8") # Replace utf-8 with the source encoding of your requested resource

এই কোডটি প্রতিক্রিয়া পড়ে, এবং একটি বাফারে বাইট রাখে। gzipমডিউল তারপর বাফার ব্যবহার সার্চ GZipFileফাংশন। এর পরে, জিজেপ করা ফাইলটি আবার বাইটে পড়তে পারে এবং শেষ পর্যন্ত সাধারণত পাঠযোগ্য পাঠ্যে ডিকোড করা যায়।

2010 থেকে আসল উত্তর:

আমরা কি ব্যবহারের জন্য আসল মান পেতে পারি link?

তদাতিরিক্ত, আমরা .encode()ইতিমধ্যে এখানে এনকোডড বাইট স্ট্রিংয়ের চেষ্টা করার সময় আমরা এখানে সাধারণত এই সমস্যাটির মুখোমুখি হই । সুতরাং আপনি প্রথম হিসাবে এটি ডিকোড করার চেষ্টা করতে পারেন

html = urllib.urlopen(link).read()
unicode_str = html.decode(<source encoding>)
encoded_str = unicode_str.encode("utf8")

উদাহরণ হিসাবে:

html = '\xa0'
encoded_str = html.encode("utf8")

ব্যর্থ হয়

UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 0: ordinal not in range(128)

যদিও:

html = '\xa0'
decoded_str = html.decode("windows-1252")
encoded_str = decoded_str.encode("utf8")

ত্রুটি ছাড়াই সফল। মনে রাখবেন যে "উইন্ডোজ -১২২২" এমন একটি জিনিস যা আমি উদাহরণ হিসাবে ব্যবহার করেছি । আমি এটি চারডিট থেকে পেয়েছি এবং এটির 0.5 আস্থা ছিল যে এটি ঠিক! (ভাল, 1-বর্ণ-দৈর্ঘ্যের স্ট্রিংয়ের সাথে দেওয়া হিসাবে, আপনি কী আশা করেন) .urlopen().read()আপনার পুনরুদ্ধার করা সামগ্রীতে প্রযোজ্য বিষয়গুলি থেকে ফিরে আসা বাইট স্ট্রিংয়ের এনকোডিংয়ে আপনাকে এটি পরিবর্তন করা উচিত ।

আমি আর একটি সমস্যা দেখতে পাচ্ছি যে .encode()স্ট্রিং পদ্ধতিটি পরিবর্তিত স্ট্রিংটি ফিরিয়ে দেয় এবং উত্সটি জায়গায় পরিবর্তিত করে না। সুতরাং self.response.out.write(html)এইচটিএমএল থাকা কোনও ধরণের বেহুদাবাদ এইচটিএমএল.এনকোডের এনকোডযুক্ত স্ট্রিং নয় (যদি এটিই আপনি মূলত লক্ষ্য করছিলেন)।

Ignacio হিসাবে পরামর্শ হিসাবে, ফিরে আসা স্ট্রিংয়ের প্রকৃত এনকোডিংয়ের জন্য উত্স ওয়েবপৃষ্ঠাটি পরীক্ষা করুন read()। এটি হয় মেটা ট্যাগগুলির মধ্যে একটিতে বা প্রতিক্রিয়াতে কন্টেন্টটাইপ শিরোনামে। প্যারামিটার হিসাবে এটি ব্যবহার করুন .decode()

তবে মনে রাখবেন যে এটি অনুমান করা উচিত নয় যে অন্যান্য বিকাশকারীরা হেডার এবং / বা মেটা অক্ষর সেট ঘোষণাগুলি প্রকৃত সামগ্রীর সাথে মেলে কিনা তা নিশ্চিত করার জন্য যথেষ্ট দায়বদ্ধ। (যা পিটা, হ্যাঁ, আমার জানা উচিত, আমি তাদের আগে একজন ছিলাম )।


1
আপনার উদাহরণে আমি মনে করি আপনি শেষ পংক্তির জন্য বোঝাতে চেয়েছিলেন encoded_str = decoded_str.encode("utf8")
আজিত অ্যান্টনি

1
আমি পাইথন ২.7.১৫ এ চেষ্টা করেছি এবং আমি এই বার্তাটি পেয়েছি raise IOError, 'Not a gzipped file'। আমি কী দোষ করেছি?
হিউন-জিউন কিম

221
>>> u'aあä'.encode('ascii', 'ignore')
'a'

metaপ্রতিক্রিয়ায় উপযুক্ত ট্যাগে বা শিরোনামটিতে চারসেটটি ব্যবহার করে আপনি ফিরে আসা স্ট্রিংটি ডিকোড করুন Content-Type, তারপরে এনকোড করুন।

পদ্ধতিটি encode(encoding, errors)ত্রুটির জন্য কাস্টম হ্যান্ডলারগুলি গ্রহণ করে। ডিফল্ট মানগুলি ছাড়াও ignore:

>>> u'aあä'.encode('ascii', 'replace')
b'a??'
>>> u'aあä'.encode('ascii', 'xmlcharrefreplace')
b'a&#12354;&#228;'
>>> u'aあä'.encode('ascii', 'backslashreplace')
b'a\\u3042\\xe4'

Https://docs.python.org/3/library/stdtyype.html#str.encode দেখুন


119

Ignacio Vazquez-Abram 'উত্তরের একটি এক্সটেনশন হিসাবে

>>> u'aあä'.encode('ascii', 'ignore')
'a'

অক্ষরগুলি থেকে উচ্চারণগুলি সরানো এবং বেস ফর্মটি মুদ্রণ করা কখনও কখনও বাঞ্ছনীয়। এটি দিয়ে সম্পন্ন করা যেতে পারে

>>> import unicodedata
>>> unicodedata.normalize('NFKD', u'aあä').encode('ascii', 'ignore')
'aa'

আপনি অন্যান্য অক্ষরগুলি (যেমন বিরামচিহ্ন) তাদের নিকটতম সমানুপাতায় অনুবাদ করতে চাইতে পারেন, উদাহরণস্বরূপ, ডান একক কোটেশন মার্কটি ইউনিকোড অক্ষর এনকোডিংয়ের সময় কোনও এসিআই এপোস্ট্রোফায় রূপান্তরিত হয় না।

>>> print u'\u2019'

>>> unicodedata.name(u'\u2019')
'RIGHT SINGLE QUOTATION MARK'
>>> u'\u2019'.encode('ascii', 'ignore')
''
# Note we get an empty string back
>>> u'\u2019'.replace(u'\u2019', u'\'').encode('ascii', 'ignore')
"'"

যদিও এটি সম্পাদন করার জন্য আরও কার্যকর উপায় রয়েছে। আরও তথ্যের জন্য এই প্রশ্নটি দেখুন পাইথনের "এই ইউনিকোডের সেরা সেরা ASCII" ডাটাবেসটি কোথায়?


4
যে প্রশ্নটি জিজ্ঞাসা করা হয়েছিল তা সমাধানে সহায়ক এবং জিজ্ঞাসিত প্রশ্নের অন্তর্নিহিত সমস্যাগুলি সমাধানের জন্য ব্যবহারিক উভয়ই কার্যকর। এটি এই ধরণের প্রশ্নের একটি মডেল উত্তর answer
শানুস্মনগাস

96

ইউনিিডকোড ব্যবহার করুন - এটি তাত্ক্ষণিক অদ্ভুত অক্ষরকে তত্ক্ষণাত্ এসিকেআইতে রূপান্তরিত করে এবং এমনকি চীনা ভাষাকে ফোনেটিক এস্কিতে রূপান্তরিত করে।

$ pip install unidecode

তারপর:

>>> from unidecode import unidecode
>>> unidecode(u'北京')
'Bei Jing'
>>> unidecode(u'Škoda')
'Skoda'

3
halle-freakin-lujah - প্রায় সময় সম্পর্কে আমি একটি উত্তর পেয়েছিলাম যা আমার পক্ষে কাজ করেছিল
অরিয়েল পার্লম্যান

10
মজাদার মান জন্য upvated। দ্রষ্টব্য যে সমস্ত অ্যাকসেন্টিউটেড ভাষায় এই মঙ্গলের শব্দ। আকোদা স্কোদা নয়। স্কোডা সম্ভবত সম্ভবত elsল এবং হোভারক্র্যাফ্ট সহ স্থূল কিছু।
সিলভাইন

1
আমি আজ অবধি বেশ কয়েকদিন ধরে ইন্টারনেট ঘষছি ... ধন্যবাদ, আপনাকে অনেক ধন্যবাদ
স্টিফেন

23

আমি আমার সমস্ত প্রকল্পে এই সহায়ক ফাংশনটি ব্যবহার করি। যদি এটি ইউনিকোডকে রূপান্তর করতে না পারে তবে এটি এড়িয়ে চলে। এটি একটি জ্যাঙ্গো লাইব্রেরিতে সংযুক্ত, তবে একটি সামান্য গবেষণা দিয়ে আপনি এটিকে বাইপাস করতে পারেন।

from django.utils import encoding

def convert_unicode_to_string(x):
    """
    >>> convert_unicode_to_string(u'ni\xf1era')
    'niera'
    """
    return encoding.smart_str(x, encoding='ascii', errors='ignore')

এটি ব্যবহারের পরে আমি আর কোনও ইউনিকোড ত্রুটি পাই না।


10
এটি সমস্যাটিকে চাপ দিচ্ছে, ডায়াগনোসিস এবং ফিক্সিং নয়। এটি বলার মতো "আমি পা কেটে ফেলার পরে, আমার আর কর্নস এবং বুনিয়াস নিয়ে সমস্যা হয় না"।
জন মাচিন

10
আমি সম্মত হই যে এটি সমস্যাটি দমন করছে। দেখে মনে হচ্ছে যে পরে যদিও প্রশ্ন। তার দ্রষ্টব্যটি দেখুন: "আমি যে কোনও কোড বাইটগুলি ত্রুটি না পেয়ে সমস্যার কারণ সৃষ্টি করছি তা কি কেবল বাদ দিতে পারি?"
গ্যাটারস্টার

3
এটি হ'ল "কিছু-স্ট্রিং" বলার মতোই en এনকোড ('এসকিআই', 'উপেক্ষা করুন')
জোশুয়া বার্নস

17
আমি আপনাকে বলতে পারি না যে আমি কারও কাছে কতটা ক্লান্ত হয়ে পড়ে এসও-তে কোনও প্রশ্ন জিজ্ঞাসা করছি এবং এই সমস্ত প্রচারের প্রতিক্রিয়া পেয়েছি। "আমার গাড়ি শুরু হবে না।" "আপনি নিজের গাড়িটি কেন শুরু করতে চান? পরিবর্তে আপনার হাঁটা উচিত।" বন্ধ কর!
শানুস্মনগাস

8
@ জনমচিন আরএসএস ফিডগুলিতে লোকেরা কী বাধা দেয়, তা আমি মাথা ঘামাই না, যদি এটি চরিত্রটি অসি না হয় তবে এটি কেটে যেতে পারে। তাদের সমস্যা। আমি কেবল চাই পাইথন আসলেই এটি বন্ধ করে দেবে এবং এর সাথে মোকাবিলা করবে, যতবার আমি 'উপেক্ষা' নির্দিষ্ট করি ততবার আমাকে ত্রুটি না দেয়। হু হু করে কে এলো?!
ব্যবহারকারী 1244215

10

ভাঙা কনসোলগুলির মতো cmd.exeএবং এইচটিএমএল আউটপুট জন্য আপনি সর্বদা ব্যবহার করতে পারেন:

my_unicode_string.encode('ascii','xmlcharrefreplace')

খাঁটি এএসসিআইআই এবং এইচটিএমএল-এ মুদ্রণযোগ্য করার সময় এটি সমস্ত অ-আস্কি অক্ষর সংরক্ষণ করবে ।

সতর্কতা : আপনি যদি ত্রুটিগুলি এড়ানোর জন্য উত্পাদন কোডে এটি ব্যবহার করেন তবে সম্ভবত আপনার কোডটিতে কিছু ভুল আছে । এর একমাত্র বৈধ ব্যবহারের কেসটি কোনও নন-ইউনিকোড কনসোলে মুদ্রণ করা বা এইচটিএমএল প্রসঙ্গে HTML সত্তাগুলিতে সহজ রূপান্তর।

এবং অবশেষে, আপনি যদি উইন্ডোতে থাকেন এবং cmd.exe ব্যবহার করেন তবে আপনি chcp 65001utf-8 আউটপুট সক্ষম করতে টাইপ করতে পারেন (লুসিডা কনসোল ফন্টের সাথে কাজ করে)। আপনার যোগ করার প্রয়োজন হতে পারে myUnicodeString.encode('utf8')


6

আপনি লিখেছেন "" "আমি ধরে নিয়েছি এর অর্থ এইচটিএমএল কোথাও কোথাও ইউনিকোডে ভুলভাবে গঠনের চেষ্টা রয়েছে।" "

এইচটিএমএলটিতে কোনও ধরণের "ইউনিকোডে চেষ্টা করা", সুগঠিত বা না থাকার আশা করা যায় না। এটি অবশ্যই প্রয়োজনবোধে কিছু এনকোডিংয়ে ইউনিকোড অক্ষরগুলি এনকোডযুক্ত থাকতে পারে যা সাধারণত সামনে সরবরাহ করা হয় ... "চারসেট" সন্ধান করুন।

আপনি ধরে নিচ্ছেন যে চরসেটটি ইউটিএফ -8 ... কোন কারণেই? আপনার ত্রুটি বার্তায় প্রদর্শিত "\ xA0" বাইটটি ইঙ্গিত দেয় যে আপনার কাছে সিঙ্গল-বাইট চারসেট যেমন সিপি 1252 থাকতে পারে।

যদি আপনি এইচটিএমএলের শুরুতে ঘোষণার বাইরে থেকে কোনও ধারণা পেতে না পারেন তবে সম্ভাব্য এনকোডিং কী তা জানতে চারডেট ব্যবহার করে চেষ্টা করুন ।

আপনি কেন আপনার প্রশ্নটিকে "রেইজেক্স" দিয়ে ট্যাগ করেছেন?

আপনার সম্পূর্ণ প্রশ্নটিকে অ-প্রশ্নে প্রতিস্থাপনের পরে আপডেট করুন :

html = urllib.urlopen(link).read()
# html refers to a str object. To get unicode, you need to find out
# how it is encoded, and decode it.

html.encode("utf8","ignore")
# problem 1: will fail because html is a str object;
# encode works on unicode objects so Python tries to decode it using 
# 'ascii' and fails
# problem 2: even if it worked, the result will be ignored; it doesn't 
# update html in situ, it returns a function result.
# problem 3: "ignore" with UTF-n: any valid unicode object 
# should be encodable in UTF-n; error implies end of the world,
# don't try to ignore it. Don't just whack in "ignore" willy-nilly,
# put it in only with a comment explaining your very cogent reasons for doing so.
# "ignore" with most other encodings: error implies that you are mistaken
# in your choice of encoding -- same advice as for UTF-n :-)
# "ignore" with decode latin1 aka iso-8859-1: error implies end of the world.
# Irrespective of error or not, you are probably mistaken
# (needing e.g. cp1252 or even cp850 instead) ;-)

4

আপনার যদি স্ট্রিং থাকে তবে আপনি স্ট্রিংয়ের জন্য এনকোডিংয়ের ধরণের রূপান্তর করতে পদ্ধতিটি lineব্যবহার করতে পারেন .encode([encoding], [errors='strict'])

line = 'my big string'

line.encode('ascii', 'ignore')

পাইথনে এএসসিআইআই এবং ইউনিকোড পরিচালনার বিষয়ে আরও তথ্যের জন্য, এটি সত্যই দরকারী একটি সাইট: https://docs.python.org/2/howto/unicode.html


1
স্ট্রিং-এ like এর মতো একটি অ্যাস্কি অক্ষর না থাকলে এটি কাজ করে না।
সাজিদ

4

আমি মনে করি উত্তরটি কেবল আছে তবে কেবল বিট এবং টুকরোয় যা সমস্যাটি দ্রুত ঠিক করা যেমন সমস্যার সমাধান করে

UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 2818: ordinal not in range(128)

আসুন একটি উদাহরণ নেওয়া যাক, ধরুন আমার কাছে ফাইল রয়েছে যা নিম্নলিখিত ফর্মটিতে কিছু তথ্য রয়েছে (এসকিআই এবং অ-এসকিআই অক্ষর সহ)

1/10/17, 21:36 - জমি: স্বাগতম ��

এবং আমরা কেবলমাত্র এসসিআই অক্ষর উপেক্ষা করে সংরক্ষণ করতে চাই।

এই কোডটি করবে:

import unicodedata
fp  = open(<FILENAME>)
for line in fp:
    rline = line.strip()
    rline = unicode(rline, "utf-8")
    rline = unicodedata.normalize('NFKD', rline).encode('ascii','ignore')
    if len(rline) != 0:
        print rline

এবং টাইপ (rline) আপনাকে দেবে

>type(rline) 
<type 'str'>

এটি (অযৌক্তিক) "বর্ধিত আসকি" মামলার ক্ষেত্রেও কাজ করে
অলিভার জেন্ডেল

1
unicodestring = '\xa0'

decoded_str = unicodestring.decode("windows-1252")
encoded_str = decoded_str.encode('ascii', 'ignore')

আমার জন্য কাজ কর


-5

দেখে মনে হচ্ছে আপনি অজগর ২.x ব্যবহার করছেন পাইথন ২.x ডিফল্ট অ্যাস্কেই এবং এটি ইউনিকোড সম্পর্কে জানে না। তাই ব্যতিক্রম।

শেবাংয়ের পরে কেবল নীচের লাইনটি পেস্ট করুন, এটি কার্যকর হবে

# -*- coding: utf-8 -*-

codingমন্তব্য একটি সর্বরোগের মহৌষধ সব নয়। আপনার ত্রুটি কেন তৈরি হচ্ছে তা আপনার জানতে হবে, যখন আপনার পাইথন উত্সে খারাপ অক্ষর রয়েছে তখন এটি কেবল জিনিসগুলি ঠিক করে। এই প্রশ্নের ক্ষেত্রে এটি প্রদর্শিত হবে না।
মার্ক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.