UnicodeDecodeError: 'ascii' codec không thể giải mã byte 0xe2 ở vị trí 13: thứ tự không nằm trong phạm vi (128)


129

Tôi đang sử dụng NLTK để thực hiện phân cụm kmeans trên tệp văn bản của mình, trong đó mỗi dòng được coi là một tài liệu. Vì vậy, ví dụ, tệp văn bản của tôi là một cái gì đó như thế này:

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 

Bây giờ mã demo tôi đang cố chạy là đây:

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

(cũng có thể được tìm thấy ở đây )

Lỗi tôi nhận được là đây:

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)

Chuyện gì đang xảy ra ở đây?

Câu trả lời:


133

Các tập tin đang được đọc như một bó strs, nhưng nó nên là unicodes. Python cố gắng chuyển đổi ngầm, nhưng không thành công. Thay đổi:

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

để giải mã rõ ràng strs thành unicode(ở đây giả sử UTF-8):

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

Nó cũng có thể được giải quyết bằng cách nhập các codecsmô-đun và sử dụng codecs.openchứ không phải là built-in open.


2
chạy dòng này.decode ('utf-8'). dải (). low (). split () cũng cho tôi lỗi tương tự. Tôi đã thêm .deocode ('utf-8')
Aman Mathur

@kathirraja: Bạn có thể cung cấp một tài liệu tham khảo cho điều đó? Theo như tôi biết, ngay cả trong Python 3, decodephương thức vẫn là cách ưa thích để giải mã chuỗi byte thành chuỗi Unicode. (Mặc dù, các loại trong câu trả lời của tôi là không phù hợp với Python 3 - cho Python 3, chúng tôi đang cố gắng để chuyển đổi từ bytestới strchứ không phải là từ strđể unicode.)
icktoofay

52

Cái này làm việc tốt cho tôi.

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

Bạn có thể thêm mã hóa tham số thứ ba để đảm bảo loại mã hóa là 'utf-8'

Lưu ý: phương pháp này hoạt động tốt trong Python3, tôi đã không thử nó trong Python2.7.


Nó không hoạt động trong Python 2.7.10:TypeError: 'encoding' is an invalid keyword argument for this function
Borhan Kazimipour

2
Nó không hoạt động trong Python 2.7.10: TypeError: 'encoding' is an invalid keyword argument for this function Điều này hoạt động tốt:import io with io.open(file_path, 'r', encoding="utf-8") as f: for line in f: do_something(line)
Borhan Kazimipour

2
Làm việc như một cơ duyên trong python3.6 Cảm ơn rất nhiều!
SRC

32

Đối với tôi đã có một vấn đề với mã hóa thiết bị đầu cuối. Thêm UTF-8 vào .bashrc đã giải quyết vấn đề:

export LC_CTYPE=en_US.UTF-8

Đừng quên tải lại .bashrc sau đó:

source ~/.bashrc

3
Tôi đã phải sử dụng export LC_ALL=C.UTF-8trên Ubuntu 18.04.3 và Python 3.6.8. Nếu không, điều này đã giải quyết vấn đề của tôi, cảm ơn.
jbaranski

31

Bạn cũng có thể thử điều này:

import sys
reload(sys)
sys.setdefaultencoding('utf8')

3
ý nghĩa của điều này là gì? Có vẻ như đó là một cái gì đó toàn cầu và không chỉ áp dụng cho tập tin này.
simeg

2
Lưu ý rằng phần trên không được dùng trong Python 3.
gated

12

Khi trên Ubuntu 18.04 sử dụng Python3.6, tôi đã giải quyết được vấn đề khi thực hiện cả hai:

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

và nếu bạn đang chạy công cụ dưới dạng dòng lệnh:

export LC_ALL=C.UTF-8

Lưu ý rằng nếu bạn đang ở trong Python2.7, bạn phải xử lý việc này khác đi. Trước tiên, bạn phải đặt mã hóa mặc định:

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

và sau đó để tải tệp bạn phải sử dụng io.openđể đặt mã hóa:

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

Bạn vẫn cần xuất env

export LC_ALL=C.UTF-8

6

Tôi đã gặp lỗi này khi cố gắng cài đặt gói python trong bộ chứa Docker. Đối với tôi, vấn đề là hình ảnh docker không có localecấu hình. Thêm mã sau vào Dockerfile đã giải quyết vấn đề cho tôi.

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

Tôi đã phải sử dụng cái này: github.com/docker-l
Library / python /issues / 13

3

Để tìm BẤT K and và TẤT CẢ lỗi unicode liên quan ... Sử dụng lệnh sau:

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

Tìm thấy của tôi trong

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

Sử dụng shed, tôi tìm thấy trình tự vi phạm. Hóa ra là một lỗi biên tập.

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

1

Bạn có thể thử điều này trước khi sử dụng job_titleschuỗi:

source = unicode(job_titles, 'utf-8')

0

Đối với python 3, mã hóa mặc định sẽ là "utf-8". Các bước sau đây được đề xuất trong tài liệu cơ sở: https://docs.python.org/2/l Library / csv.html#csv-examples trong trường hợp có vấn đề

  1. Tạo một chức năng

    def utf_8_encoder(unicode_csv_data):
        for line in unicode_csv_data:
            yield line.encode('utf-8')
  2. Sau đó sử dụng chức năng bên trong đầu đọc, ví dụ

    csv_reader = csv.reader(utf_8_encoder(unicode_csv_data))

0

python3x trở lên

  1. tải tập tin trong luồng byte:

    body = '' cho các dòng trong open ('website / index.html', 'rb'): decodingLine = lines.decode ('utf-8') body = body + decodingLine.strip ()

  2. sử dụng cài đặt toàn cầu:

    nhập io nhập sys sys.stdout = io.TextIOWrapper (sys.stdout.buffer, mã hóa = 'utf-8')


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.