UnicodeEncodeError: 'ascii' codec bileşeni 20 konumunda u '\ xa0' karakterini kodlayamıyor: sıra değeri aralıkta değil (128)


1296

Farklı web sayfalarından (farklı sitelerde) getirilen metinden unicode karakterlerle ilgili sorunlar yaşıyorum. BeautifulSoup kullanıyorum.

Sorun, hatanın her zaman yeniden üretilememesidir; bazen bazı sayfalarla çalışır ve bazen a UnicodeEncodeError. Aklıma gelen her şeyi denedim ve yine de Unicode ile ilgili bir tür hata atmadan sürekli çalışan bir şey bulamadım.

Kodun sorunlara neden olan bölümlerinden biri aşağıda gösterilmiştir:

agent_telno = agent.find('div', 'agent_contact_number')
agent_telno = '' if agent_telno is None else agent_telno.contents[0]
p.agent_info = str(agent_contact + ' ' + agent_telno).strip()

Yukarıdaki snippet çalıştırıldığında SOME dizelerinde üretilen bir yığın izlemesi:

Traceback (most recent call last):
  File "foobar.py", line 792, in <module>
    p.agent_info = str(agent_contact + ' ' + agent_telno).strip()
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 20: ordinal not in range(128)

Bunun bazı sayfaların (veya daha spesifik olarak bazı sitelerdeki sayfaların) kodlanmış olabileceğini, bazılarının ise kodlanmamış olabileceğinden şüpheleniyorum. Tüm siteler İngiltere'de yerleşiktir ve İngiltere tüketimi için veri sağlar - bu nedenle içselleştirme veya İngilizce dışında herhangi bir şeyle yazılmış metinlerle ilgili herhangi bir sorun yoktur.

Herkes bu sorunu sürekli olarak gidermek böylece bunu çözmek için herhangi bir fikir var mı?



Bu noktayı , bu şeyler için onlinegdb.com/online_python_interpreter kullanmayın . Bu yorumlayıcıyı denemek için kullanıyordum ve Unicode için doğru yapılandırılmamış! Her zaman 'B' \ nnn '' biçiminde baskı yapıyordum ... tek istediğim bir guillemet olduğunda! Bir VM üzerinde çalıştı ve chr () kullanarak beklendiği gibi çalıştı
JGFMK

4
Bunu dene import os; import locale; os.environ["PYTHONIOENCODING"] = "utf-8"; myLocale=locale.setlocale(category=locale.LC_ALL, locale="en_GB.UTF-8"); ... print(myText.encode('utf-8', errors='ignore')).
hhh

@ snhpet'inizi çalıştırdım NameError: 'myText' tanımlı değil
KHAN irfan

9
Senaryonuzu çalıştırmadan önce kabuğundaki PYTHONIOENCODING ayarını yapmayı deneyin :$ export PYTHONIOENCODING=utf8
Noam Manos

Yanıtlar:


1361

Python Unicode NASIL belgesini okumalısınız . Bu hata ilk örnektir .

Temel olarak, strunicode'dan kodlanmış metne / bayta dönüştürmek için kullanmayı bırakın .

Bunun yerine, .encode()dizeyi kodlamak için uygun şekilde kullanın :

p.agent_info = u' '.join((agent_contact, agent_telno)).encode('utf-8').strip()

veya tamamen unicode ile çalışabilirsiniz.


23
kabul! bana öğretilen iyi bir kural "unicode sandviç" fikrini kullanmaktır. Betiğiniz dış dünyadan gelen baytları kabul eder, ancak tüm işlemler unicode ile yapılmalıdır. Sadece verilerinizi çıkarmaya hazır olduğunuzda, baytlara geri dönüştürülmelidir!
12'de Andbdrew

256
Birisi printbununla karıştırılırsa, garip bir şey buldum: terminalim utf-8 kullanıyor ve utf-8 dizelerim güzel çalışıyor. Ancak program çıktımı bir dosyaya koyduğumda a atar UnicodeEncodeError. Çıkışı (Bir dosya veya bir boruya) yönlendirilir Aslında,, ben bulmak sys.stdout.encodingolduğunu None! Üzerinde durmak .encode('utf-8')problemi çözer.
drevicko

93
@drevicko: PYTHONIOENCODING=utf-8bunun yerine yani Unicode dizelerini yazdırın ve ortamın beklenen kodlamayı ayarlamasına izin verin.
jfs

1
@steinar: her durumda hiçbir şey geçerli değildir. Genel olarak, bir kullanıcı yardımcı programınızı uygulamak için Python'u kullanmanıza dikkat etmemelidir (herhangi bir nedenle başka bir dilde yeniden uygulamaya karar verirseniz arayüz değişmemelidir) ve bu nedenle kullanıcının python- spesifik envvarlar. Kullanıcıyı karakter kodlaması belirtmeye zorlamak kötü kullanıcı arayüzüdür; gerekirse karakter kodlamasını rapor biçiminde gömün. Not: Hiçbir sabit kodlama genel durumda "mantıklı varsayılan" olamaz.
jfs

13
Bu kötü ve kafa karıştırıcı bir tavsiye. İnsanların str kullanmasının nedeni, nesnenin zaten bir dize DEĞİLDİR, bu nedenle çağrılacak bir .encode()yöntem yoktur .
Cerin

433

Bu klasik bir python unicode ağrı noktası! Aşağıdakileri göz önünde bulundur:

a = u'bats\u00E0'
print a
 => batsà

Şimdiye kadar her şey yolunda, ancak str (a) dersek, ne olacağını görelim:

str(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 4: ordinal not in range(128)

Oh daldırma, bu hiç kimseye iyi gelmeyecek! Hatayı düzeltmek için baytları açık bir şekilde .encode ile kodlayın ve python'a hangi codec bileşenini kullanacağını söyleyin:

a.encode('utf-8')
 => 'bats\xc3\xa0'
print a.encode('utf-8')
 => batsà

Voil \ u00E0!

Sorun, str () öğesini çağırdığınızda, python'un verdiğiniz baytları denemek ve kodlamak için varsayılan karakter kodlamasını kullanmasıdır; Sorunu çözmek için, .encode ('whatever_unicode') kullanarak python'a verdiğiniz dize ile nasıl başa çıkılacağını söylemelisiniz. Çoğu zaman, utf-8 kullanarak iyi olmalısınız.

Bu konuyla ilgili mükemmel bir açıklama için Ned Batchelder'ın PyCon konuşmasına buradan bakın: http://nedbatchelder.com/text/unipain.html


85
Kişisel not: ".encode" yazmaya çalışırken yanlışlıkla ".unicode" yazmayın, neden hiçbir şeyin işe yaramadığını merak edin.
Atla Huffman

9
İyi tavsiye. Ancak, dizeler olabilecek veya olmayabilecek nesneleri yazdırmak için str (x) kullanırken bunun yerine ne yaparsınız? str (x), x bir sayı, tarih saati, boole veya normal dize ise çalışır. Aniden onun bir unicode ise çalışmayı durdurur. Aynı davranışı elde etmenin bir yolu var mı ya da şimdi nesnenin .encode ve str () kullanmak için string olup olmadığını test etmek için bir IF denetimi eklememiz gerekiyor mu?
Dirk R

Aynı soru Nonedeğer ile de sorulabilir .
Vadorequest

210

Sembolleri kaldırmak ve dizeyi aşağıdaki gibi dize olarak tutmaya devam etmek için etrafımda zarif bir iş buldum:

yourstring = yourstring.encode('ascii', 'ignore').decode('ascii')

Yoksay seçeneğini kullanmanın tehlikeli olduğunu fark etmek önemlidir, çünkü burada görüldüğü gibi, herhangi bir unicode (ve uluslararasılaştırma) desteğini kullanan koddan sessizce düşürür (unicode'u dönüştürün):

>>> u'City: Malmö'.encode('ascii', 'ignore').decode('ascii')
'City: Malm'

17
Günümü gün ettin! Utf-8 için yourstring = yourstring.encode('utf-8', 'ignore').decode('utf-8')
şunları

benim için bu işe yaradı ama benim durumum farklı, ben dosya adlarını kaydediyordu ve adında "/" sahip oldu ve yol yoktu bu yüzden .replace ("/", "") kullanmak zorunda ve böylece kaydetti mayın senaryosu. ascii görmezden gelinirken 'utf-8' davası için de çalışıyor.
Akash Kandpal

1
@ harrypotter0 dosya yollarını doğru bir şekilde kullanmak için os.path.join(), platformlar arası programlama yapmaya başladığınızda çok iyi bir alışkanlıktır. :)
login_not_failed

152

iyi her şeyi denedim ama yardımcı olmadı, etrafında googling sonra aşağıdaki düşündüm ve yardımcı oldu. python 2.7 kullanımda.

# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')

7
Bunu yapma. stackoverflow.com/questions/3828723/... , böyle cevapları ne zaman olsa stackoverflow.com/a/31137935/2141635 hatanın aramak sonuçlarının en yakın iyi bir fikir gibi görünebilir neden görebilirsiniz.
Padraic Cunningham

21
Bu konudaki neredeyse tüm önerileri denedim ve gerçekten hiçbiri benim için çalışmadı. Sonunda bunu denedim. Ve gerçekten basit ve iyi çalışan SADECE biri. Birisi "Bunu yapma, o zaman basit bir çözümle gel. Aksi takdirde bunu kullan. Çünkü iyi çalışan bir kopya ve geçmiş bir çözüm.
Richard de Ree

4
Bu python3'te nasıl yapılabilir? Bilmek mutlu olurdu.
Kanerva Peter

3
Çok fazla hayal kırıklığından sonra bu işe yaradı. Çok teşekkürler.
Avraham Zhurba

4
Ben sadece bir eklemek istiyorumif sys.version_info.major < 3:
Prof. Falken sözleşme

87

Yazdırmanın başarısız olmasına neden olan küçük bir sorun, ortam değişkenlerinizin yanlış ayarlanmasıdır. burada LC_ALL "C" olarak ayarlanmıştır. Debian'da bunu yapmaktan vazgeçiyorlar : Locale'de Debian wiki

$ echo $LANG
en_US.utf8
$ echo $LC_ALL 
C
$ python -c "print (u'voil\u00e0')"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 4: ordinal not in range(128)
$ export LC_ALL='en_US.utf8'
$ python -c "print (u'voil\u00e0')"
voilà
$ unset LC_ALL
$ python -c "print (u'voil\u00e0')"
voilà

Tam olarak aynı sorunu var, çok kötü rapor vermeden önce kontrol etmedi . Çok teşekkürler. Bu arada, ilk iki komutu ile değiştirebilirsiniz env|grep -E '(LC|LANG)'.
Dmitry Verhoturov

Yanlış kodlama konusunda sadece iki sentim. Sık sık mc"subshell mode" ( Ctrl-O) kullanıyorum ve bash için aşağıdaki takma adı eklediğimi de unuttum alias mc="LANG=en_EN.UTF-8 mc". Dolayısıyla, ru_RU.UTF-8dahili olarak dayanan kötü yazılmış komut dosyaları çalıştırmaya çalıştığımda , sadece ölüyorlar. Gerçek sorunu keşfetmeden önce bu iş parçacığından çok şey denedim. :)
login_not_failed

HARİKASIN. GSUTIL'de, bu sorun nedeniyle rsync'im başarısız oldu. LC_ALL düzeltildi ve her şey şarap gibi iyi çalışıyor. <3 TEŞEKKÜR EDERİZ <3
dsignr

27

Benim için işe yarayan şuydu:

BeautifulSoup(html_text,from_encoding="utf-8")

Umarım bu birine yardımcı olur.


25

Aslında vakalarımın çoğunda, bu karakterleri çıkarmak çok daha basit:

s = mystring.decode('ascii', 'ignore')

26
"Mükemmel" genellikle yaptığı şey değildir. Düzgün bir şekilde nasıl başa çıkacağınızı anlamanız gereken şeyleri atar.
tripleee

7
sadece "o" (ingilizce olmayan) karakterleri sıyırma bir çözüm değildir çünkü python tüm dilleri desteklemesi gerekir sanmıyorum?
alemol

8
Downvoted. Bu hiç de doğru bir çözüm değil. Unicode ile nasıl çalışacağınızı öğrenin: joelonsoftware.com/articles/Unicode.html
Andrew Ferrier

4
Bakın, bu özel cevabı sunmanın en mantıklı yolu şu şekildedir: ascii'nin belirli diller ve kullanıcılar üzerinde belirli bir ayrıcalık verdiğini kabul etmek - bu, bir küfür, ilk geçişi hackleyebilen kullanıcılar için istismar edilebilecek kaçış kapağıdır . , tam unicode desteği uygulanmadan önce potansiyel olarak ön çalışma için komut dosyası oluşturun.
lol

5
Dahili bir şirket uygulamasında stdout'a ingilizce metin yazdırması gereken bir komut dosyası yazıyorsam, sorunun çözülmesini istiyorum. Nasıl uygun görürsen.
kagronick

25

Sorun şu ki, unicode bir karakter yazdırmaya çalışıyorsunuz, ancak terminaliniz bunu desteklemiyor.

Bunu language-pack-endüzeltmek için paketi yüklemeyi deneyebilirsiniz :

sudo apt-get install language-pack-en

desteklenen tüm paketler (Python dahil) için İngilizce çeviri verisi güncellemeleri sağlar. Gerekirse farklı bir dil paketi yükleyin (hangi karakterleri yazdırmaya çalıştığınıza bağlı olarak).

Bazı Linux dağıtımlarında, varsayılan İngilizce yerel ayarlarının doğru bir şekilde ayarlandığından emin olmak gerekir (böylece unicode karakterler kabuk / terminal tarafından işlenebilir). Bazen kurmak, manuel olarak yapılandırmaktan daha kolaydır.

Sonra kodu yazarken, kodunuzda doğru kodlamayı kullandığınızdan emin olun.

Örneğin:

open(foo, encoding='utf-8')

Hala sorun yaşıyorsanız, sistem yapılandırmanızı tekrar kontrol edin, örneğin:

  • /etc/default/localeÖrneğin, yerel ayar dosyanız ( )

    LANG="en_US.UTF-8"
    LC_ALL="en_US.UTF-8"

    veya:

    LC_ALL=C.UTF-8
    LANG=C.UTF-8
  • Kabuktaki LANG/ LC_CTYPEiçindeki değer .

  • Kabuğunuzun hangi yerel ayarı desteklediğini kontrol edin:

    locale -a | grep "UTF-8"

Yeni VM'de problemin ve çözümün gösterilmesi.

  1. VM'yi başlatın ve hazırlayın (örn. Kullanarak vagrant):

    vagrant init ubuntu/trusty64; vagrant up; vagrant ssh

    Bakınız: mevcut Ubuntu kutuları . .

  2. Unicode karakterleri yazdırma (ticari marka işareti gibi ):

    $ python -c 'print(u"\u2122");'
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    UnicodeEncodeError: 'ascii' codec can't encode character u'\u2122' in position 0: ordinal not in range(128)
  3. Şimdi kuruluyor language-pack-en:

    $ sudo apt-get -y install language-pack-en
    The following extra packages will be installed:
      language-pack-en-base
    Generating locales...
      en_GB.UTF-8... /usr/sbin/locale-gen: done
    Generation complete.
  4. Şimdi sorun çözülmeli:

    $ python -c 'print(u"\u2122");'
    
  5. Aksi takdirde, aşağıdaki komutu deneyin:

    $ LC_ALL=C.UTF-8 python -c 'print(u"\u2122");'
    

1
language-pack-enPython veya bu soru ile ne ilgisi var? AFAIK, mesajlara dil çevirisi sağlayabilir, ancak kodlama ile ilgisi yoktur
Alastair McCormack

2
Bazı Linux dağıtımlarında, özellikle Terminalde Python betiği çalıştırırken, varsayılan İngilizce yerel ayarlarının doğru ayarlandığından emin olmak gerekir. Bir noktada benim için çalıştı. Bkz: karakter kodlama
kenorb

Ah tamam. İngilizce olmayan bir yerel ayar kullanmak istiyor musunuz? Sanırım kullanıcı da /etc/locale.genkullanmadan önce kendi yerel ayarı sağlamak için düzenlemek zorunda kalacak ?
Alastair McCormack

1
@AlastairMcCormack dışarı Yorumlananlar LANGdan /etc/default/locale(aynı /etc/locale.genve ran does't varoldukları için) locale-gen, ama etmedi yardımı. language-pack-enTam olarak ne yaptığından emin değilim , çünkü çok fazla belge bulamadım ve içeriğini listelemek çok yardımcı olmuyor.
kenorb

1
zaten bir masaüstü sisteminde utf-8 yerel ayarlarının bulunma olasılığı düşüktür, yani herhangi bir şey yüklemenize gerek yoktur, sadece LANG/ LC_CTYPE/ LC_ALLyerine yapılandırın (örn LANG=C.UTF-8.).
jfs

19

Kabukta:

  1. Aşağıdaki komutla desteklenen UTF-8 yerel ayarını bulun:

    locale -a | grep "UTF-8"
  2. Komut dosyasını çalıştırmadan önce dışa aktarın, örneğin:

    export LC_ALL=$(locale -a | grep UTF-8)

    veya manuel olarak:

    export LC_ALL=C.UTF-8
  3. Özel karakter yazdırarak test edin, örn :

    python -c 'print(u"\u2122");'

Yukarıda Ubuntu'da test edilmiştir.


Evet, bu en iyi kısa yanıt, kaynak kodunu kullanmak için değiştiremiyoruz. Encode
Luat Nguyen - Neo.Mxn0

16

Betiğinizin başına (veya ikinci satır olarak) aşağıdaki satırı ekleyin:

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

Bu python kaynak kodu kodlamasının tanımıdır. Daha fazla bilgi için PEP 263 .


2
Harici dosyadan yüklenen işlenmiş utf-8 kodlamaları içerdiğinde bu sorunu çözmez. Bu sadece verilen python betiğinin kendisinde yazılan hazır bilgiler için yardımcı olur ve sadece python yorumlayıcısı için bir ipucudur, ancak metin işleme üzerinde hiçbir etkisi yoktur.
Mikaelblomkvistsson

16

İşte bazı "polis çıkma" cevaplarının yeniden canlandırılması. Burada dile getirilen protestolara rağmen, zahmetli karakterleri / karakter dizilerini atmanın iyi bir çözüm olduğu durumlar var.

def safeStr(obj):
    try: return str(obj)
    except UnicodeEncodeError:
        return obj.encode('ascii', 'ignore').decode('ascii')
    except: return ""

Test ediliyor:

if __name__ == '__main__': 
    print safeStr( 1 ) 
    print safeStr( "test" ) 
    print u'98\xb0'
    print safeStr( u'98\xb0' )

Sonuçlar:

1
test
98°
98

Öneri: Bu işlevi şu şekilde adlandırmak isteyebilirsiniz: toAscii yerine ? Bu bir tercih meselesi.

Bu Python 2 için yazılmıştır. Python 3 için kullanmak bytes(obj,"ascii")yerine kullanmak isteyeceğinize inanıyorum str(obj). Bunu henüz test etmedim, ama bir noktada cevabı gözden geçireceğim.


8

Her zaman aşağıdaki kodu python dosyalarının ilk iki satırına koydu:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

6

Burada basit yardımcı fonksiyonlar bulundu .

def safe_unicode(obj, *args):
    """ return the unicode representation of obj """
    try:
        return unicode(obj, *args)
    except UnicodeDecodeError:
        # obj is byte string
        ascii_text = str(obj).encode('string_escape')
        return unicode(ascii_text)

def safe_str(obj):
    """ return the byte string representation of obj """
    try:
        return str(obj)
    except UnicodeEncodeError:
        # obj is unicode
        return unicode(obj).encode('unicode_escape')

(ASCII kodlama kullanarak bayt keyfi Unicode dizesi dönüştürmek için) şunu kullanabilirsiniz bytestring kaçan almak için backslashreplacehata işleyicisi: u'\xa0'.encode('ascii', 'backslashreplace'). Bu temsilden kaçınmanız ve ortamınızı ascii olmayan karakterleri kabul edecek şekilde yapılandırmanıza rağmen - bu 2016!
jfs

Yeni Yılınız Kutlu Olsun @JFSebastian. Ben sadece Python-Unicode sorunu ile sinirli ve nihayet çalışan bu çözümü aldım. Bunu bilmiyordum. Neyse bahşiş için teşekkürler.
Parag Tyagi -morpheus-



3

Ben sadece aşağıdakileri kullandım:

import unicodedata
message = unicodedata.normalize("NFKD", message)

Bununla ilgili belgelerin ne dediğini kontrol edin:

unicodedata.normalize (form, unistr) Unicode dizesi unistr için normal form formunu döndürür. Form için geçerli değerler 'NFC', 'NFKC', 'NFD' ve 'NFKD'dir.

Unicode standardı, kanonik eşdeğerlik ve uyumluluk eşdeğerliği tanımına dayalı olarak bir Unicode dizesinin çeşitli normalleştirme formlarını tanımlar. Unicode'da birkaç karakter çeşitli şekillerde ifade edilebilir. Örneğin, U + 00C7 karakteri (CEDILLA İLE LATİN SERMAYE MEKTUBU C) U + 0043 dizisi olarak ifade edilebilir (LATIN SERMAYE MEKTUBU C) U + 0327 (CEDILLA KOMBİNASYONU).

Her karakter için iki normal form vardır: normal C formu ve normal D formu. Normal D formu (NFD) kanonik ayrışma olarak da bilinir ve her karakteri ayrıştırılmış forma çevirir. Normal C formu (NFC) önce kanonik bir ayrışma uygular, sonra önceden birleştirilmiş karakterleri yeniden oluşturur.

Bu iki forma ek olarak, uyumluluk denkliğine dayanan iki normal form daha vardır. Unicode'da normalde diğer karakterlerle birleştirilecek belirli karakterler desteklenir. Örneğin, U + 2160 (ROMAN SAYISAL BİR) gerçekten U + 0049 (LATIN SERMAYE MEKTUBU I) ile aynı şeydir. Ancak, mevcut karakter kümeleriyle (ör. Gb2312) uyumluluk için Unicode'da desteklenir.

Normal form KD (NFKD) uyumluluk ayrışmasını uygular, yani tüm uyumluluk karakterlerini eşdeğerleriyle değiştirir. Normal form KC (NFKC) önce uyumluluk ayrışmasını, ardından kanonik bileşimi uygular.

İki unicode dizge normalleştirilmiş ve bir insan okuyucuyla aynı görünse bile, birinin karakterleri birleştirmesi ve diğerinin olmaması durumunda, eşit karşılaştırmayabilirler.

Benim için çözer. Basit ve kolay.


3

Aşağıdaki çözüm benim için çalıştı, Sadece ekledi

u "Dize"

(dizeyi unicode olarak gösterir) dizemden önce.

result_html = result.to_html(col_space=1, index=False, justify={'right'})

text = u"""
<html>
<body>
<p>
Hello all, <br>
<br>
Here's weekly summary report.  Let me know if you have any questions. <br>
<br>
Data Summary <br>
<br>
<br>
{0}
</p>
<p>Thanks,</p>
<p>Data Team</p>
</body></html>
""".format(result_html)

3

Ne yazık ki bu en azından Python 3'te çalışıyor ...

Python 3

Bazen hata çevre değişkenlerinde ve dolayısıyla

import os
import locale
os.environ["PYTHONIOENCODING"] = "utf-8"
myLocale=locale.setlocale(category=locale.LC_ALL, locale="en_GB.UTF-8")
... 
print(myText.encode('utf-8', errors='ignore'))

kodlamada hatalar dikkate alınmaz.


2

Bu sorunu yaşadım ve Google beni buraya getirdi, bu yüzden burada genel çözümlere eklemek için bu benim için işe yaradı:

# 'value' contains the problematic data
unic = u''
unic += value
value = unic

Okuduktan sonra bu fikrim vardı Ned'in sunumunu .

Yine de bunun neden işe yaradığını tam olarak iddia etmiyorum. Eğer herhangi biri bu cevabı düzenleyebilir veya açıklamak için bir yorum yazabilirse, bunu takdir edeceğim.


3
Nedir typedeğerin? bundan önce ve sonra? Bence neden işe yarıyor unic += valueki, unic = unic + valuebir dize ve bir unicode eklediğinizle aynı olanı yaparak , python daha sonra sonuç unicolarak daha kesin bir tür için unicode varsayar (yani ne zaman düşünün a = float(1) + int(1), abir şamandıra haline gelir) ve daha sonra value = unicişaret valueyeniye unicunicode olması umulur nesne.
Tom Myddeltyn

2

Çalışırken bu hatayı aldık manage.py migrateDjango'da yerel fikstürlerle .

Kaynağımız # -*- coding: utf-8 -*-beyanı içeriyordu , MySQL utf8 için doğru şekilde yapılandırıldı ve Ubuntu uygun dil paketi ve değerlerine sahipti./etc/default/locale .

Sorun Django kapsayıcısında (docker kullanıyoruz) LANG env var .

Taşıma LANGişlemlerini en_US.UTF-8yeniden çalıştırmadan önce kapsayıcının ayarlanması ve yeniden başlatılması sorunu çözdü.


1

Burada birçok cevap (örneğin @agf ve @Andbdrew) OP sorununun en acil yönlerini ele aldı.

Bununla birlikte, büyük ölçüde göz ardı edilen ve benim gibi herkes için çok önemli olan, Python'daki kodlamaları anlamaya çalışırken son derece önemli olan önemli ama önemli bir yön olduğunu düşünüyorum: Python 2 vs Python 3 karakter temsili yönetimi çok farklı . Sürüm farkında olmadan Python'daki kodlamaları okuyan insanlarla ilgili büyük bir karışıklık parçası gibi hissediyorum.

Spolsky'nin karakter gösterimlerine ve Unicode'a girişini okuyarak ve sonra Python 2 ve Python 3'te Unicode'da Batchelder'a geçerek OP sorununun temel nedenini anlamak isteyen herkese öneriyorum .


evet, hatam python 2.7, 'a'.format (u'ñ') üzerindeydi ve doğru çözüm .encode ('utf-8') kullanmak değil, her zaman unicode dizeleri kullanmaktır (varsayılan olarak python 3'te) ): u'a'.format (u'ñ '),
Rogelio

1

Değişkenin str'ye (değişken) dönüştürülmesinden kaçının. Bazen, soruna neden olabilir.

Kaçınılması gereken basit ipucu:

try: 
    data=str(data)
except:
    data = data #Don't convert to String

Yukarıdaki örnek Kodlama hatasını da çözecektir.


senin kadar bu doens't işi sadece haricinde hata içine edeceğiz
Aurele Collinet

0

Eğer böyle bir şey varsa, bunu packet_data = "This is data"başlattıktan hemen sonra bir sonraki satırda yapın packet_data:

unic = u''
packet_data = unic


0

Unicode karakterleri çıktısını almaya çalışırken bu sorunu yaşadım stdout, ancaksys.stdout.write daha ziyade baskı daha (yani sıra farklı bir dosyaya çıktı destekleyebileceği anlamına).

BeautifulSoup'un kendi belgelerinden , bunu codec kütüphanesi ile çözdüm:

import sys
import codecs

def main(fIn, fOut):
    soup = BeautifulSoup(fIn)
    # Do processing, with data including non-ASCII characters
    fOut.write(unicode(soup))

if __name__ == '__main__':
    with (sys.stdin) as fIn: # Don't think we need codecs.getreader here
        with codecs.getwriter('utf-8')(sys.stdout) as fOut:
            main(fIn, fOut)

0

Bu sorun genellikle bir django projesi Apache kullanarak dağıtıldığında oluşur. Çünkü Apache / etc / sysconfig / httpd içinde LANG = C ortam değişkenini ayarlar. Sadece dosyayı açın ve bu ayara yorum yapın (veya zevkinize değiştirin). Veya WSGIDaemonProcess komutunun lang seçeneğini kullanın, bu durumda farklı sanal ana bilgisayarlara farklı LANG ortam değişkeni ayarlayabilirsiniz.


0

Önerilen çözüm benim için işe yaramadı ve tüm ascii olmayan karakterleri dökerek yaşayabilirdim, bu yüzden

s = s.encode('ascii',errors='ignore')

bu da beni atmayan ve hata atmayan bir şey bıraktı.


0

Bu çalışacak:

 >>>print(unicodedata.normalize('NFD', re.sub("[\(\[].*?[\)\]]", "", "bats\xc3\xa0")).encode('ascii', 'ignore'))

Çıktı:

>>>bats
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.