UnicodeDecodeError: 'ascii' codec tidak dapat mendekodekan byte 0xe2 di posisi 13: ordinal tidak dalam jangkauan (128)

129

Saya menggunakan NLTK untuk melakukan pengelompokan kmeans pada file teks saya di mana setiap baris dianggap sebagai dokumen. Jadi misalnya, file teks saya kira-kira seperti ini:

belong finger death punch <br>
hasty <br>
mike hasty walls jericho <br>
jägermeister rules <br>
rules bands follow performing jägermeister stage <br>
approach 

Sekarang kode demo yang saya coba jalankan adalah ini:

import sys

import numpy
from nltk.cluster import KMeansClusterer, GAAClusterer, euclidean_distance
import nltk.corpus
from nltk import decorators
import nltk.stem

stemmer_func = nltk.stem.EnglishStemmer().stem
stopwords = set(nltk.corpus.stopwords.words('english'))

@decorators.memoize
def normalize_word(word):
    return stemmer_func(word.lower())

def get_words(titles):
    words = set()
    for title in job_titles:
        for word in title.split():
            words.add(normalize_word(word))
    return list(words)

@decorators.memoize
def vectorspaced(title):
    title_components = [normalize_word(word) for word in title.split()]
    return numpy.array([
        word in title_components and not word in stopwords
        for word in words], numpy.short)

if __name__ == '__main__':

    filename = 'example.txt'
    if len(sys.argv) == 2:
        filename = sys.argv[1]

    with open(filename) as title_file:

        job_titles = [line.strip() for line in title_file.readlines()]

        words = get_words(job_titles)

        # cluster = KMeansClusterer(5, euclidean_distance)
        cluster = GAAClusterer(5)
        cluster.cluster([vectorspaced(title) for title in job_titles if title])

        # NOTE: This is inefficient, cluster.classify should really just be
        # called when you are classifying previously unseen examples!
        classified_examples = [
                cluster.classify(vectorspaced(title)) for title in job_titles
            ]

        for cluster_id, title in sorted(zip(classified_examples, job_titles)):
            print cluster_id, title

(yang juga dapat ditemukan di sini )

Kesalahan yang saya terima adalah ini:

Traceback (most recent call last):
File "cluster_example.py", line 40, in
words = get_words(job_titles)
File "cluster_example.py", line 20, in get_words
words.add(normalize_word(word))
File "", line 1, in
File "/usr/local/lib/python2.7/dist-packages/nltk/decorators.py", line 183, in memoize
result = func(*args)
File "cluster_example.py", line 14, in normalize_word
return stemmer_func(word.lower())
File "/usr/local/lib/python2.7/dist-packages/nltk/stem/snowball.py", line 694, in stem
word = (word.replace(u"\u2019", u"\x27")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 13: ordinal not in range(128)

Apa yang terjadi disini?

pengguna2602812
sumber

Jawaban:

133

File sedang dibaca sebagai sekelompok strs, tetapi harus unicodes. Python mencoba mengkonversi secara implisit, tetapi gagal. Perubahan:

job_titles = [line.strip() for line in title_file.readlines()]

untuk secara eksplisit men-decode strs ke unicode(di sini dengan asumsi UTF-8):

job_titles = [line.decode('utf-8').strip() for line in title_file.readlines()]

Hal ini juga bisa diselesaikan dengan mengimpor para codecsmodul dan menggunakan codecs.opendaripada built-in open.

icktoofay
sumber
2
menjalankan baris ini.decode ('utf-8'). strip (). lower (). split () juga memberi saya kesalahan yang sama. Saya telah menambahkan .deocode ('utf-8')
Aman Mathur
@kathirraja: Bisakah Anda memberikan referensi untuk itu? Sejauh yang saya tahu, bahkan dalam Python 3, decodemetode ini tetap merupakan cara yang lebih disukai untuk mendekode string byte ke string Unicode. (Meskipun, tipe-tipe dalam jawaban saya tidak cocok untuk Python 3 - untuk Python 3, kami mencoba untuk mengubah dari bytesmenjadi strdaripada dari strke unicode.)
icktoofay
52

Ini berfungsi baik untuk saya.

f = open(file_path, 'r+', encoding="utf-8")

Anda dapat menambahkan pengkodean parameter ketiga untuk memastikan jenis pengkodean adalah 'utf-8'

Catatan: metode ini berfungsi dengan baik di Python3, saya tidak mencobanya di Python2.7.

uestcfei
sumber
Itu tidak bekerja di Python 2.7.10:TypeError: 'encoding' is an invalid keyword argument for this function
Borhan Kazimipour
2
Itu tidak bekerja di Python 2.7.10: TypeError: 'encoding' is an invalid keyword argument for this function Ini berfungsi dengan baik:import io with io.open(file_path, 'r', encoding="utf-8") as f: for line in f: do_something(line)
Borhan Kazimipour
2
Bekerja seperti pesona di python3.6 Terima kasih banyak!
SRC
32

Bagi saya ada masalah dengan pengkodean terminal. Menambahkan UTF-8 ke .bashrc memecahkan masalah:

export LC_CTYPE=en_US.UTF-8

Jangan lupa memuat ulang .bashrc sesudahnya:

source ~/.bashrc
Georgi Karadzhov
sumber
3
Saya harus menggunakan export LC_ALL=C.UTF-8Ubuntu 18.04.3 dan Python 3.6.8. Kalau tidak, ini menyelesaikan masalah saya, terima kasih.
jbaranski
31

Anda juga dapat mencoba ini:

import sys
reload(sys)
sys.setdefaultencoding('utf8')
Siva S
sumber
3
apa akibat dari hal ini? Kedengarannya seperti sesuatu yang global dan tidak hanya berlaku untuk file ini.
simeg
2
Perhatikan bahwa di atas tidak digunakan lagi dalam Python 3.
gented
12

Ketika di Ubuntu 18.04 menggunakan Python3.6 saya telah memecahkan masalah dengan melakukan keduanya:

with open(filename, encoding="utf-8") as lines:

dan jika Anda menjalankan alat sebagai baris perintah:

export LC_ALL=C.UTF-8

Perhatikan bahwa jika Anda menggunakan Python2.7, Anda harus melakukannya secara berbeda. Pertama, Anda harus mengatur penyandian default:

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

dan kemudian untuk memuat file yang harus Anda gunakan io.openuntuk mengatur pengkodean:

import io
with io.open(filename, 'r', encoding='utf-8') as lines:

Anda masih perlu mengekspor env

export LC_ALL=C.UTF-8
loretoparisi
sumber
6

Saya mendapat kesalahan ini ketika mencoba menginstal paket python dalam wadah Docker. Bagi saya, masalahnya adalah bahwa gambar buruh pelabuhan tidak localedikonfigurasi. Menambahkan kode berikut ke Dockerfile memecahkan masalah bagi saya.

# Avoid ascii errors when reading files in Python
RUN apt-get install -y \
  locales && \
  locale-gen en_US.UTF-8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'
Jacob Stern
sumber
Saya harus menggunakan ini: github.com/docker-library/python/issues/13
mayrop
3

Untuk menemukan ANY dan ALL error terkait unicode ... Menggunakan perintah berikut:

grep -r -P '[^\x00-\x7f]' /etc/apache2 /etc/letsencrypt /etc/nginx

Ditemukan milikku di

/etc/letsencrypt/options-ssl-nginx.conf:        # The following CSP directives don't use default-src as 

Dengan menggunakan shed, saya menemukan urutan yang menyinggung. Ternyata itu merupakan kesalahan editor.

00008099:     C2  194 302 11000010
00008100:     A0  160 240 10100000
00008101:  d  64  100 144 01100100
00008102:  e  65  101 145 01100101
00008103:  f  66  102 146 01100110
00008104:  a  61  097 141 01100001
00008105:  u  75  117 165 01110101
00008106:  l  6C  108 154 01101100
00008107:  t  74  116 164 01110100
00008108:  -  2D  045 055 00101101
00008109:  s  73  115 163 01110011
00008110:  r  72  114 162 01110010
00008111:  c  63  099 143 01100011
00008112:     C2  194 302 11000010
00008113:     A0  160 240 10100000
John Greene
sumber
1

Anda dapat mencoba ini sebelum menggunakan job_titlesstring:

source = unicode(job_titles, 'utf-8')
Aminah Nuraini
sumber
0

Untuk python 3, penyandian default adalah "utf-8". Langkah-langkah berikut disarankan dalam dokumentasi dasar: https://docs.python.org/2/library/csv.html#csv-examples dalam hal terjadi masalah

  1. Buat fungsi

    def utf_8_encoder(unicode_csv_data):
        for line in unicode_csv_data:
            yield line.encode('utf-8')
  2. Kemudian gunakan fungsi di dalam pembaca, misalnya

    csv_reader = csv.reader(utf_8_encoder(unicode_csv_data))
iamigham
sumber
0

python3x atau lebih tinggi

  1. memuat file dalam aliran byte:

    body = '' untuk baris di open ('website / index.html', 'rb'): decodedLine = lines.decode ('utf-8') body = body + decodedLine.strip () return body

  2. gunakan pengaturan global:

    import io import sys sys.stdout = io.TextIOWrapper (sys.stdout.buffer, enkode = 'utf-8')

io besar
sumber
0

Gunakan, open(fn, 'rb').read().decode('utf-8')bukan hanyaopen(fn).read()

Ganesh Kharad
sumber