UnicodeEncodeError: 'ascii' codec tidak dapat menyandikan karakter u '\ xa0' di posisi 20: ordinal tidak dalam jangkauan (128)


1298

Saya mengalami masalah berurusan dengan karakter unicode dari teks yang diambil dari halaman web yang berbeda (di situs yang berbeda). Saya menggunakan BeautifulSoup.

Masalahnya adalah bahwa kesalahan tidak selalu dapat direproduksi; kadang-kadang bekerja dengan beberapa halaman, dan kadang-kadang, itu muntah dengan melempar a UnicodeEncodeError. Saya telah mencoba hampir semua yang dapat saya pikirkan, namun saya belum menemukan apa pun yang bekerja secara konsisten tanpa melemparkan semacam kesalahan terkait Unicode.

Salah satu bagian dari kode yang menyebabkan masalah ditunjukkan di bawah ini:

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()

Berikut ini adalah jejak tumpukan yang dihasilkan pada BEBERAPA string ketika snipet di atas dijalankan:

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)

Saya menduga ini karena beberapa halaman (atau lebih spesifiknya, halaman dari beberapa situs) mungkin dikodekan, sementara yang lain mungkin tidak di-kode. Semua situs berbasis di Inggris dan menyediakan data yang dimaksudkan untuk konsumsi Inggris - sehingga tidak ada masalah yang berkaitan dengan internalisasi atau berurusan dengan teks yang ditulis dalam apa pun selain bahasa Inggris.

Adakah yang punya ide bagaimana menyelesaikan ini sehingga saya dapat memperbaiki masalah ini secara KONSISTEN?


1
Jika Anda mendapatkan kesalahan ini sebagai pengguna alih-alih sebagai pengembang, periksa serverfault.com/questions/54591/... dan askubuntu.com/questions/599808/...
That Brazilian Guy

Saya akan menambahkan titik ini jangan gunakan onlinegdb.com/online_python_interpreter untuk hal ini. Menggunakan penerjemah itu untuk mencoba berbagai hal dan tidak dikonfigurasi dengan benar untuk Unicode! Selalu mencetak dalam format 'B' \ nnn '' ... padahal yang saya inginkan hanyalah guillemet! Mencoba pada VM dan bekerja segera seperti yang diharapkan menggunakan chr ()
JGFMK

4
Coba ini 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

@hhh Saya menjalankan cuplikan Anda NameError: nama 'myText' tidak ditentukan
KHAN irfan

9
Cobalah untuk mengatur PYTHONIOENCODING di shell, sebelum mengeksekusi skrip Anda:$ export PYTHONIOENCODING=utf8
Noam Manos

Jawaban:


1364

Anda perlu membaca Python Unicode HOWTO . Kesalahan ini adalah contoh pertama .

Pada dasarnya, hentikan penggunaan struntuk mengonversi dari unicode ke teks / byte yang disandikan.

Sebagai gantinya, gunakan dengan benar .encode()untuk menyandikan string:

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

atau bekerja sepenuhnya dalam unicode.


23
sepakat! aturan praktis yang saya ajarkan adalah menggunakan ide "unicode sandwich". Skrip Anda menerima byte dari dunia luar, tetapi semua pemrosesan harus dilakukan dalam unicode. Hanya ketika Anda siap untuk mengeluarkan data Anda, maka data tersebut harus dikembalikan ke byte!
Andbdrew

256
Jika ada orang lain yang bingung dengan ini, saya menemukan hal yang aneh: terminal saya menggunakan utf-8, dan ketika printsaya utf-8 string saya berfungsi dengan baik. Namun ketika saya mem-pipe output program saya ke file, ia melempar a UnicodeEncodeError. Bahkan, ketika output diarahkan (ke file atau pipa), saya menemukan bahwa sys.stdout.encodingadalah None! Menangani .encode('utf-8')masalah memecahkan masalah.
drevicko

93
@drevicko: gunakan PYTHONIOENCODING=utf-8sebagai contoh , cetak string Unicode dan biarkan lingkungan untuk mengatur pengkodean yang diharapkan.
jfs

1
@steinar: tidak ada yang valid dalam setiap kasus. Secara umum, pengguna seharusnya tidak peduli bahwa Anda menggunakan Python untuk mengimplementasikan utilitas Anda (antarmuka tidak akan berubah jika Anda memutuskan untuk mengimplementasikannya kembali dalam bahasa lain untuk alasan apa pun) dan oleh karena itu Anda tidak boleh berharap bahwa pengguna bahkan menyadari tentang python- utusan khusus. Ini adalah UI yang buruk untuk memaksa pengguna untuk menentukan pengkodean karakter; sematkan penyandian karakter dalam format laporan jika perlu. Catatan: tidak ada pengkodean hardcode yang bisa menjadi "default yang masuk akal" dalam kasus umum.
jfs

13
Ini saran yang buruk dan membingungkan. Alasan orang menggunakan str adalah karena objek BUKAN sebuah string, jadi tidak ada .encode()metode untuk memanggil.
Cerin

434

Ini adalah titik nyeri unicode python klasik! Pertimbangkan yang berikut ini:

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

Sejauh ini semuanya baik-baik saja, tetapi jika kita sebut str (a), mari kita lihat apa yang terjadi:

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 celup, itu tidak akan ada gunanya bagi siapa pun! Untuk memperbaiki kesalahan, enkode byte secara eksplisit dengan .encode dan beri tahu python apa codec yang akan digunakan:

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

Voil \ u00E0!

Masalahnya adalah ketika Anda memanggil str (), python menggunakan pengkodean karakter default untuk mencoba dan menyandikan byte yang Anda berikan, yang dalam kasus Anda terkadang merupakan representasi karakter unicode. Untuk memperbaiki masalah, Anda harus memberi tahu python cara menangani string yang Anda berikan dengan menggunakan .encode ('whatever_unicode'). Biasanya, Anda harus menggunakan utf-8.

Untuk eksposisi yang sangat baik tentang topik ini, lihat pembicaraan PyCon Ned Batchelder di sini: http://nedbatchelder.com/text/unipain.html


85
Catatan pribadi: Ketika mencoba mengetik ".encode" jangan mengetik ".unicode" secara tidak sengaja, lalu bertanya-tanya mengapa tidak ada yang berfungsi.
Lewati Huffman

9
Saran yang bagus. Tetapi apa yang Anda lakukan sebagai gantinya ketika Anda menggunakan str (x) untuk mencetak objek yang mungkin atau mungkin bukan string? str (x) berfungsi jika x adalah angka, waktu tanggal, boolean, atau string normal. Tiba-tiba jika sebuah unicode berhenti bekerja. Apakah ada cara untuk mendapatkan perilaku yang sama atau apakah kita sekarang perlu menambahkan cek IF untuk menguji apakah objek tersebut adalah string untuk menggunakan .encode, dan str () jika tidak?
Dirk R

Pertanyaan yang sama bisa ditanyakan dengan Nonenilai.
Vadorequest

210

Saya menemukan pekerjaan yang elegan di sekitar bagi saya untuk menghapus simbol dan terus menjaga string sebagai string sebagai berikut:

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

Penting untuk memperhatikan bahwa menggunakan opsi abaikan berbahaya karena diam-diam menjatuhkan dukungan unicode (dan internasionalisasi) dari kode yang menggunakannya, seperti yang terlihat di sini (convert unicode):

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

17
Anda membuat hari saya! Untuk utf-8, itu sudah cukup untuk dilakukan:yourstring = yourstring.encode('utf-8', 'ignore').decode('utf-8')
luca76

bagi saya ini berhasil tetapi kasus saya berbeda, saya menyimpan nama file dan memiliki "/" dalam nama dan path tidak ada jadi saya harus menggunakan .replace ("/", "") dan dengan demikian disimpan naskah tambang. sementara mengabaikan ascii juga berfungsi untuk kasus 'utf-8' juga.
Akash Kandpal

1
@ harrypotter0 untuk menggabungkan path file yang digunakan dengan benar os.path.join(), itu kebiasaan yang sangat baik ketika Anda mulai melakukan pemrograman lintas platform. :)
login_not_failed

152

baik saya mencoba segalanya tetapi tidak membantu, setelah googling saya pikir berikut dan itu membantu. python 2.7 sedang digunakan.

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

7
Jangan lakukan ini. stackoverflow.com/questions/3828723/… , meskipun ketika Anda memiliki jawaban seperti ini stackoverflow.com/a/31137935/2141635 di dekat bagian atas hasil ketika Anda mencari kesalahan, saya bisa melihat mengapa itu mungkin tampak seperti ide yang bagus.
Padraic Cunningham

21
Saya mencoba hampir semua saran dalam topik ini dan benar-benar tidak ada yang berhasil untuk saya. Akhirnya saya mencoba yang ini. Dan itu benar-benar SATU-SATUNYA yang berhasil dan sederhana. Jika seseorang berkata "Jangan lakukan ini, maka datang dengan Solusi sederhana. Kalau tidak gunakan yang ini. Karena ini adalah copy pekerjaan yang baik dan solusi masa lalu.
Richard de Ree

4
Bagaimana ini bisa dilakukan di python3? Senang bisa tahu.
Kanerva Peter

3
Setelah begitu banyak frustrasi yang satu ini berhasil. Terima kasih banyak.
Avraham Zhurba

4
Saya baru saja menambahkanif sys.version_info.major < 3:
Kontrak Prof. Falken dilanggar

87

Masalah halus yang menyebabkan bahkan cetak gagal adalah salah mengatur variabel lingkungan Anda, mis. di sini LC_ALL diatur ke "C". Di Debian mereka tidak menyarankan untuk mengaturnya: Debian wiki di Lokal

$ 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à

Punya masalah yang sama persis, sangat buruk saya tidak memeriksanya sebelum melaporkan . Terima kasih banyak. Omong-omong, Anda dapat mengganti dua perintah pertama dengan env|grep -E '(LC|LANG)'.
Dmitry Verhoturov

Hanya dua sen saya pada masalah penyandian yang salah. Saya sering menggunakan mcdalam "modus subkulit" ( Ctrl-O) dan saya juga lupa bahwa saya menambahkan alias berikut untuk bash: alias mc="LANG=en_EN.UTF-8 mc". Jadi ketika saya mencoba menjalankan skrip yang ditulis dengan buruk yang mengandalkan ru_RU.UTF-8internal, mereka hanya mati. Mencoba banyak hal dari utas ini sebelum saya menemukan masalah sebenarnya. :)
login_not_failed

KAMU MENAKJUBKAN. Di GSUTIL, rsync saya gagal karena masalah ini persis. Memperbaiki LC_ALL dan semuanya berfungsi dengan baik seperti anggur. <3 TERIMA KASIH <3
dsignr

27

Bagi saya, yang berhasil adalah:

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

Semoga ini bisa membantu seseorang.


25

Saya benar-benar menemukan bahwa dalam sebagian besar kasus saya, hanya menghapus karakter-karakter itu jauh lebih sederhana:

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

26
"Sempurna" biasanya tidak apa yang dilakukannya. Itu membuang hal-hal yang Anda harus mencari cara untuk menangani dengan benar.
tripleee

7
hanya menghilangkan karakter "itu" (non-Inggris) bukan solusi karena python harus mendukung semua bahasa, bukan begitu?
alemol

8
Diturunkan. Ini bukan solusi yang benar sama sekali. Pelajari cara bekerja dengan Unicode: joelonsoftware.com/articles/Unicode.html
Andrew Ferrier

4
Begini, cara paling bijak untuk menyajikan jawaban khusus ini adalah dengan cara ini: mengakui bahwa ascii menganugerahkan hak istimewa tertentu pada bahasa dan pengguna tertentu - ini adalah pintu keluar yang dapat dieksploitasi untuk para pengguna yang mungkin meretas sepintas lalu, sepintas lalu , skrip bersama berpotensi untuk pekerjaan pendahuluan sebelum dukungan unicode penuh diimplementasikan.
lol

5
Jika saya menulis skrip yang hanya perlu mencetak teks bahasa Inggris ke stdout di aplikasi internal perusahaan, saya hanya ingin masalah itu hilang. Apapun yang berhasil.
kagronick

25

Masalahnya adalah Anda mencoba mencetak karakter unicode, tetapi terminal Anda tidak mendukungnya.

Anda dapat mencoba menginstal language-pack-enpaket untuk memperbaikinya:

sudo apt-get install language-pack-en

yang menyediakan pembaruan data terjemahan Bahasa Inggris untuk semua paket yang didukung (termasuk Python). Instal paket bahasa yang berbeda jika perlu (tergantung karakter mana yang Anda coba cetak).

Pada beberapa distribusi Linux diperlukan untuk memastikan bahwa bahasa Inggris default diatur dengan benar (sehingga karakter unicode dapat ditangani oleh shell / terminal). Terkadang lebih mudah untuk menginstalnya, daripada mengonfigurasinya secara manual.

Kemudian ketika menulis kode, pastikan Anda menggunakan pengkodean yang tepat dalam kode Anda.

Sebagai contoh:

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

Jika Anda masih mengalami masalah, periksa kembali konfigurasi sistem Anda, seperti:

  • File lokal Anda (/etc/default/locale ), yang seharusnya memiliki mis

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

    atau:

    LC_ALL=C.UTF-8
    LANG=C.UTF-8
  • Nilai dari LANG/LC_CTYPE dalam shell.

  • Periksa lokasi yang didukung shell Anda oleh:

    locale -a | grep "UTF-8"

Menunjukkan masalah dan solusi dalam VM baru.

  1. Inisialisasi dan berikan VM (mis. Menggunakan vagrant):

    vagrant init ubuntu/trusty64; vagrant up; vagrant ssh

    Lihat: kotak Ubuntu yang tersedia ..

  2. Mencetak karakter unicode (seperti tanda merek dagang ):

    $ 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. Sekarang menginstal 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. Sekarang masalah harus dipecahkan:

    $ python -c 'print(u"\u2122");'
    
  5. Jika tidak, coba perintah berikut:

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

1
Apa language-pack-enhubungannya dengan Python atau pertanyaan ini? AFAIK, ini mungkin menyediakan terjemahan bahasa ke pesan tetapi tidak ada hubungannya dengan penyandian
Alastair McCormack

2
Pada beberapa distribusi Linux diperlukan untuk memastikan bahwa bahasa Inggris default diatur dengan benar, terutama ketika menjalankan skrip Python di Terminal. Itu berhasil untuk saya pada satu titik. Lihat: pengkodean karakter
kenorb

Ah, baiklah. Maksud Anda jika Anda ingin menggunakan lokal non-Inggris? Saya kira pengguna juga harus mengedit /etc/locale.genuntuk memastikan lokal mereka dibangun sebelum menggunakannya?
Alastair McCormack

1
@AlastairMcCormack Mengomentari LANGdari /etc/default/locale(seperti tidak /etc/locale.genada) dan berlari locale-gen, tetapi tidak membantu. Saya tidak yakin apa language-pack-ensebenarnya yang harus dilakukan, karena saya tidak menemukan banyak dokumentasi dan daftar isinya tidak banyak membantu.
kenorb

1
tidak mungkin bahwa tidak ada utf-8 lokal pada sistem desktop yaitu, kemungkinan Anda tidak perlu menginstal apa pun, cukup konfigurasikan LANG/ LC_CTYPE/ LC_ALLsebagai gantinya (misalnya, LANG=C.UTF-8).
jfs

19

Dalam shell:

  1. Temukan lokal UTF-8 yang didukung oleh perintah berikut:

    locale -a | grep "UTF-8"
  2. Ekspor, sebelum menjalankan skrip, misalnya:

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

    atau secara manual suka:

    export LC_ALL=C.UTF-8
  3. Uji dengan mencetak karakter khusus, misalnya :

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

Di atas diuji di Ubuntu.


Ya ini adalah jawaban singkat terbaik, kami tidak dapat mengubah kode sumber untuk menggunakan .encode
Luat Nguyen - Neo.Mxn0

16

Tambahkan baris di bawah ini di awal skrip Anda (atau sebagai baris kedua):

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

Itulah definisi pengkodean kode sumber python. Info lebih lanjut dalam PEP 263 .


2
Ini tidak menyelesaikan masalah ketika teks yang diolah dimuat dari file eksternal berisi pengkodean utf-8. Ini membantu hanya untuk literal yang ditulis dalam skrip python yang diberikan itu sendiri dan hanya merupakan petunjuk bagi penerjemah python, tetapi tidak berdampak pada pemrosesan teks.
Mikaelblomkvistsson

16

Berikut adalah pengulangan dari beberapa jawaban yang disebut "cop out". Ada situasi di mana membuang karakter / string yang merepotkan adalah solusi yang baik, meskipun ada protes yang disuarakan di sini.

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

Mengujinya:

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

Hasil:

1
test
98°
98

Saran: Anda mungkin ingin menamai fungsi ini toAsciisebagai gantinya? Itu masalah preferensi.

Ini ditulis untuk Python 2. Untuk Python 3, saya yakin Anda ingin menggunakan bytes(obj,"ascii")daripada str(obj). Saya belum menguji ini, tetapi saya akan pada beberapa titik dan merevisi jawabannya.


8

Saya selalu meletakkan kode di bawah ini dalam dua baris pertama dari file python:

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

6

Fungsi pembantu sederhana ditemukan di sini .

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')

Untuk mendapatkan melarikan diri bytestring (untuk mengkonversi sewenang-wenang Unicode string untuk byte menggunakan ascii encoding), Anda bisa menggunakan backslashreplacehandler error: u'\xa0'.encode('ascii', 'backslashreplace'). Meskipun Anda harus menghindari representasi tersebut dan mengonfigurasi lingkungan Anda untuk menerima karakter non-ascii sebagai gantinya - ini adalah 2016!
jfs

Selamat Tahun Baru @JFSebastian. Saya baru saja frustrasi dengan masalah Python-Unicode dan akhirnya mendapatkan solusi ini yang berfungsi. Saya tidak tahu tentang ini. Bagaimanapun terima kasih atas tipnya.
Parag Tyagi



3

Saya hanya menggunakan yang berikut ini:

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

Periksa apa yang dikatakan dokumentasi tentangnya:

unicodedata.normalize (form, unistr) Mengembalikan bentuk form normal untuk unistr string Unicode. Nilai yang valid untuk formulir adalah 'NFC', 'NFKC', 'NFD', dan 'NFKD'.

Standar Unicode mendefinisikan berbagai bentuk normalisasi string Unicode, berdasarkan definisi kesetaraan kanonik dan kesetaraan kompatibilitas. Dalam Unicode, beberapa karakter dapat diekspresikan dengan berbagai cara. Misalnya, karakter U + 00C7 (LATIN CAPITAL LETTER C WITH CEDILLA) juga dapat dinyatakan sebagai urutan U + 0043 (LATIN MODAL LETTER C) U + 0327 (COMBINING CEDILLA).

Untuk setiap karakter, ada dua bentuk normal: bentuk normal C dan bentuk normal D. Bentuk normal D (NFD) juga dikenal sebagai dekomposisi kanonik, dan menerjemahkan setiap karakter ke dalam bentuknya yang terurai. Bentuk normal C (NFC) pertama-tama menerapkan dekomposisi kanonik, kemudian menyusun kembali karakter yang digabungkan.

Selain dua bentuk ini, ada dua bentuk normal tambahan berdasarkan kesetaraan kompatibilitas. Dalam Unicode, karakter tertentu didukung yang biasanya akan disatukan dengan karakter lain. Misalnya, U + 2160 (ROMAN NUMERAL ONE) benar-benar sama dengan U + 0049 (LATIN CAPITAL LETTER I). Namun, itu didukung dalam Unicode untuk kompatibilitas dengan set karakter yang ada (misalnya gb2312).

Bentuk normal KD (NFKD) akan menerapkan dekomposisi kompatibilitas, yaitu mengganti semua karakter kompatibilitas dengan padanannya. Bentuk normal KC (NFKC) pertama kali menerapkan dekomposisi kompatibilitas, diikuti oleh komposisi kanonik.

Bahkan jika dua string unicode dinormalisasi dan terlihat sama untuk pembaca manusia, jika satu memiliki kombinasi karakter dan yang lainnya tidak, mereka mungkin tidak dapat dibandingkan.

Menyelesaikannya untukku. Sederhana dan mudah.


3

Solusi di bawah ini bekerja untuk saya, Baru ditambahkan

kamu "Tali"

(mewakili string sebagai unicode) sebelum string saya.

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

Sayangnya ini berfungsi di Python 3 setidaknya ...

Python 3

Kadang-kadang kesalahan ada dalam variabel lingkungan dan mengkondisikannya

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'))

di mana kesalahan diabaikan dalam penyandian.


2

Saya baru saja mengalami masalah ini, dan Google membawa saya ke sini, jadi hanya untuk menambahkan solusi umum di sini, inilah yang bekerja untuk saya:

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

Saya mendapat ide ini setelah membaca presentasi Ned .

Saya tidak mengklaim sepenuhnya mengerti mengapa ini berhasil. Jadi jika ada yang bisa mengedit jawaban ini atau memberikan komentar untuk menjelaskan, saya akan menghargainya.


3
Apa typenilainya? sebelum dan sesudah ini? Saya pikir mengapa yang berhasil adalah bahwa dengan melakukan unic += valueyang sama seperti unic = unic + valueAnda menambahkan string dan unicode, di mana python kemudian mengasumsikan unicode untuk resultan unicyaitu jenis yang lebih tepat (pikirkan ketika Anda melakukan ini a = float(1) + int(1), amenjadi pelampung) dan kemudian value = unicmenunjuk valueke unicobjek baru yang kebetulan unicode.
Tom Myddeltyn

2

Kami menemukan kesalahan ini saat menjalankan manage.py migrate di Django dengan perlengkapan lokal.

Sumber kami berisi # -*- coding: utf-8 -*-deklarasi, MySQL telah dikonfigurasi dengan benar untuk utf8 dan Ubuntu memiliki paket bahasa dan nilai-nilai yang sesuai di dalamnya/etc/default/locale .

Masalahnya hanyalah bahwa wadah Django (kami menggunakan buruh pelabuhan) tidak ada LANG env var.

Mengatur LANGke en_US.UTF-8dan memulai kembali wadah sebelum menjalankan migrasi kembali memperbaiki masalah.


1

Banyak jawaban di sini (@agf dan @Andbdrew misalnya) telah membahas aspek paling langsung dari pertanyaan OP.

Namun, saya pikir ada satu aspek halus namun penting yang sebagian besar telah diabaikan dan yang penting bagi semua orang yang seperti saya berakhir di sini ketika mencoba untuk memahami penyandian dalam Python: Python 2 vs Python 3 pengelolaan representasi karakter sangat berbeda . Saya merasa seperti sebagian besar kebingungan di luar sana ada hubungannya dengan orang-orang yang membaca tentang penyandian dengan Python tanpa menyadari versi.

Saya menyarankan siapa pun yang tertarik untuk memahami akar penyebab masalah OP untuk memulai dengan membaca pengantar Spolsky untuk representasi karakter dan Unicode dan kemudian pindah ke Batchelder pada Unicode di Python 2 dan Python 3.


ya, kesalahan saya ada di python 2.7, 'a'.format (u'ñ'), dan solusi yang benar adalah tidak menggunakan .encode ('utf-8') tetapi gunakan string selalu unicode, (default di python 3 ): u'a'.format (u'ñ '),
Rogelio

1

Cobalah untuk menghindari konversi variabel ke str (variabel). Terkadang, ini dapat menyebabkan masalah.

Kiat sederhana yang harus dihindari:

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

Contoh di atas juga akan menyelesaikan kesalahan Encode.


ini tidak berfungsi karena Anda hanya akan mengalami kesalahan di kecuali
Aurele Collinet

0

Jika Anda memiliki sesuatu seperti packet_data = "This is data"kemudian lakukan ini di baris berikutnya, tepat setelah menginisialisasi packet_data:

unic = u''
packet_data = unic


0

Saya mengalami masalah ini untuk mencoba menampilkan karakter Unicode stdout, tetapi dengan sys.stdout.write, alih-alih mencetak (sehingga saya dapat mendukung keluaran ke file yang berbeda juga).

Dari dokumentasi BeautifulSoup sendiri , saya menyelesaikan ini dengan perpustakaan codec:

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

Masalah ini sering terjadi ketika proyek Django menggunakan Apache. Karena Apache menetapkan variabel lingkungan LANG = C di / etc / sysconfig / httpd. Cukup buka file dan komentar (atau ubah ke flavior Anda) pengaturan ini. Atau gunakan opsi lang dari perintah WSGIDaemonProcess, dalam hal ini Anda akan dapat mengatur variabel lingkungan LANG yang berbeda ke virtualhosts yang berbeda.


0

Solusi yang disarankan tidak bekerja untuk saya, dan saya bisa hidup dengan membuang semua karakter non ascii, jadi

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

yang membuat saya kehilangan sesuatu.


0

Ini akan berhasil:

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

Keluaran:

>>>bats
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.