Kode saya hanya mengikis halaman web, lalu mengubahnya menjadi Unicode.
html = urllib.urlopen(link).read()
html.encode("utf8","ignore")
self.response.out.write(html)
Tapi saya mendapat 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)
Saya berasumsi itu berarti HTML berisi beberapa upaya yang salah di Unicode. Bisakah saya melepaskan kode byte apa pun yang menyebabkan masalah alih-alih mendapatkan kesalahan?
c2
byte atau Anda mungkin akan mendapatkan kesalahan decode: hexutf8.com/?q=C2A0Jawaban:
Pembaruan 2018:
Pada Februari 2018, menggunakan kompresi seperti
gzip
telah menjadi sangat populer (sekitar 73% dari semua situs web menggunakannya, termasuk situs besar seperti Google, YouTube, Yahoo, Wikipedia, Reddit, Stack Overflow, dan Stack Exchange Network).Jika Anda melakukan decode sederhana seperti pada jawaban asli dengan respons yang di-gzip, Anda akan mendapatkan kesalahan seperti atau mirip dengan ini:
Untuk men-decode respons gzpipped, Anda perlu menambahkan modul berikut (dengan Python 3):
Catatan: Dalam Python 2 Anda akan menggunakan
StringIO
sebagai gantinyaio
Kemudian Anda dapat menguraikan konten seperti ini:
Kode ini membaca respons, dan menempatkan byte dalam buffer. The
gzip
modul kemudian membaca buffer menggunakanGZipFile
fungsi. Setelah itu, file yang di-gzip dapat dibaca menjadi byte lagi dan diterjemahkan ke teks yang biasanya dapat dibaca pada akhirnya.Jawaban Asli dari 2010:
Bisakah kita mendapatkan nilai aktual yang digunakan
link
?Selain itu, kami biasanya menghadapi masalah ini di sini ketika kami mencoba untuk
.encode()
byte string yang sudah dikodekan. Jadi, Anda dapat mencoba memecahkan kode itu terlebih dahulu seperti padaSebagai contoh:
Gagal dengan
Sementara:
Berhasil tanpa kesalahan. Perhatikan bahwa "windows-1252" adalah sesuatu yang saya gunakan sebagai contoh . Saya mendapat ini dari chardet dan memiliki 0,5 keyakinan bahwa itu benar! (well, seperti yang diberikan dengan string 1-karakter-panjang, apa yang Anda harapkan) Anda harus mengubahnya ke pengkodean string byte yang dikembalikan dari
.urlopen().read()
ke apa yang berlaku untuk konten yang Anda ambil.Masalah lain yang saya lihat di sana adalah bahwa
.encode()
metode string mengembalikan string yang dimodifikasi dan tidak mengubah sumber di tempatnya. Jadi agak tidak berguna untuk memilikiself.response.out.write(html)
html bukan string yang disandikan dari html.encode (jika itu yang awalnya Anda tuju).Seperti yang disarankan Ignacio, periksa halaman web sumber untuk pengkodean sebenarnya dari string yang dikembalikan
read()
. Entah itu di salah satu tag Meta atau di header ContentType dalam respons. Gunakan itu sebagai parameter untuk.decode()
.Namun perlu dicatat bahwa tidak boleh diasumsikan bahwa pengembang lain cukup bertanggung jawab untuk memastikan deklarasi header dan / atau karakter meta cocok dengan konten yang sebenarnya. (Yang merupakan PITA, ya, saya harus tahu, saya adalah salah satu dari mereka sebelumnya).
sumber
encoded_str = decoded_str.encode("utf8")
raise IOError, 'Not a gzipped file'
. Apa kesalahan saya?Dekode ulang string yang Anda dapatkan kembali, menggunakan charset di
meta
tag yang sesuai di respons atau diContent-Type
header, lalu menyandikan.Metode
encode(encoding, errors)
menerima penangan khusus untuk kesalahan. Nilai defaultnya, selain ituignore
, adalah:Lihat https://docs.python.org/3/library/stdtypes.html#str.encode
sumber
Sebagai perpanjangan dari jawaban Ignacio Vazquez-Abrams
Kadang-kadang diinginkan untuk menghapus aksen dari karakter dan mencetak formulir dasar. Ini bisa dicapai dengan
Anda mungkin juga ingin menerjemahkan karakter lain (seperti tanda baca) ke padanan terdekatnya, misalnya karakter unicode MARK QUOTATION QUOTATION RIGHT SINGLE tidak dapat dikonversi ke ascii APOSTROPHE saat penyandian.
Meskipun ada cara yang lebih efisien untuk mencapai ini. Lihat pertanyaan ini untuk perincian lebih lanjut Di mana basis data "ASCII terbaik untuk Unicode" Python ini?
sumber
Gunakan unidecode - bahkan mengubah karakter aneh menjadi ascii secara instan, dan bahkan mengubah bahasa Mandarin menjadi fonetik ascii.
kemudian:
sumber
Saya menggunakan fungsi pembantu ini di seluruh proyek saya. Jika tidak dapat mengonversi unicode, ia mengabaikannya. Ini mengikat ke perpustakaan Django, tetapi dengan sedikit riset Anda bisa melewati itu.
Saya tidak lagi mendapatkan kesalahan unicode setelah menggunakan ini.
sumber
Untuk konsol yang rusak seperti
cmd.exe
dan output HTML Anda selalu dapat menggunakan:Ini akan mempertahankan semua karakter non-ascii sambil membuatnya dicetak dalam ASCII murni dan dalam HTML.
PERINGATAN : Jika Anda menggunakan ini dalam kode produksi untuk menghindari kesalahan maka kemungkinan besar ada sesuatu yang salah dalam kode Anda . Satu-satunya kasus penggunaan yang valid untuk ini adalah mencetak ke konsol non-unicode atau konversi mudah ke entitas HTML dalam konteks HTML.
Dan akhirnya, jika Anda berada di windows dan menggunakan cmd.exe maka Anda dapat mengetik
chcp 65001
untuk mengaktifkan output utf-8 (berfungsi dengan font Konsol Lucida). Anda mungkin perlu menambahkanmyUnicodeString.encode('utf8')
.sumber
Anda menulis "" "Saya berasumsi itu berarti HTML berisi beberapa upaya salah unicode di suatu tempat." ""
HTML TIDAK diharapkan berisi segala jenis "upaya unicode", baik atau tidak. Pasti berisi karakter Unicode dikodekan dalam beberapa pengkodean, yang biasanya disediakan di depan ... cari "charset".
Anda tampaknya menganggap bahwa rangkaian karakter adalah UTF-8 ... atas dasar apa? Byte "\ xA0" yang ditampilkan dalam pesan kesalahan Anda menunjukkan bahwa Anda mungkin memiliki charset byte tunggal misalnya cp1252.
Jika Anda tidak bisa memahami pernyataan di awal HTML, coba gunakan chardet untuk mencari tahu apa yang dimaksud dengan pengkodean.
Mengapa Anda menandai pertanyaan Anda dengan "regex"?
Perbarui setelah Anda mengganti seluruh pertanyaan Anda dengan non-pertanyaan:
sumber
Jika Anda memiliki string
line
, Anda dapat menggunakan.encode([encoding], [errors='strict'])
metode untuk string untuk mengonversi jenis penyandian.line = 'my big string'
line.encode('ascii', 'ignore')
Untuk informasi lebih lanjut tentang penanganan ASCII dan unicode dengan Python, ini adalah situs yang sangat berguna: https://docs.python.org/2/howto/unicode.html
sumber
Saya pikir jawabannya ada tetapi hanya dalam potongan - potongan, yang membuatnya sulit untuk memperbaiki masalah seperti
Mari kita ambil contoh, Misalkan saya memiliki file yang memiliki beberapa data dalam bentuk berikut (berisi karakter ascii dan non-ascii)
1/10/17, 21:36 - Tanah: Selamat datang ��
dan kami ingin mengabaikan dan hanya melestarikan karakter ascii.
Kode ini akan berfungsi:
dan ketik (rline) akan memberi Anda
sumber
Bekerja untukku
sumber
Sepertinya Anda menggunakan python 2.x. Python 2.x default ke ascii dan tidak tahu tentang Unicode. Karena itu pengecualian.
Cukup salin baris di bawah ini setelah shebang, itu akan berhasil
sumber
coding
komentar bukan obat-semua sihir. Anda perlu tahu mengapa kesalahan dibuat, ini hanya memperbaiki hal-hal ketika ada karakter buruk di sumber Python Anda. Tampaknya tidak demikian halnya dengan pertanyaan ini.