UnicodeDecodeError: ตัวแปลงสัญญาณ 'ascii' ไม่สามารถถอดรหัสไบต์ 0xe2 ในตำแหน่ง 13: ลำดับไม่อยู่ในช่วง (128)


129

ฉันใช้ NLTK เพื่อดำเนินการจัดกลุ่ม kmeans ในไฟล์ข้อความของฉันซึ่งแต่ละบรรทัดถือเป็นเอกสาร ตัวอย่างเช่นไฟล์ข้อความของฉันเป็นดังนี้:

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 

ตอนนี้รหัสสาธิตที่ฉันพยายามเรียกใช้คือ:

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

(ซึ่งสามารถพบได้ที่นี่ )

ข้อผิดพลาดที่ฉันได้รับคือ:

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)

เกิดอะไรขึ้นที่นี่?

คำตอบ:


133

กำลังอ่านไฟล์เป็นจำนวนstrมาก แต่ควรเป็นunicodes Python พยายามแปลงโดยปริยาย แต่ล้มเหลว เปลี่ยนแปลง:

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

เพื่อถอดรหัสstrs เป็นอย่างชัดเจนunicode(ที่นี่สมมติว่า UTF-8):

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

นอกจากนี้ยังสามารถแก้ไขได้โดยการนำเข้าโมดูลและการใช้มากกว่าในตัวcodecscodecs.openopen


2
เรียกใช้ line.decode นี้ ('utf-8'). strip (). lower (). split () ยังทำให้ฉันมีข้อผิดพลาดเดียวกัน ฉันได้เพิ่ม. deocode ('utf-8')
Aman Mathur

@kathirraja: คุณช่วยอ้างอิงได้ไหม? เท่าที่ฉันรู้แม้ใน Python 3 decodeวิธีนี้ยังคงเป็นวิธีที่ต้องการในการถอดรหัสสตริงไบต์เป็นสตริง Unicode (แม้ว่าประเภทในคำตอบของฉันไม่เหมาะสำหรับ Python 3 - สำหรับ Python 3 เรากำลังพยายามแปลงจากbytesเป็นstrแทนที่จะเป็นจากstrเป็นunicode)
icktoofay

52

วิธีนี้ใช้ได้ดีสำหรับฉัน

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

คุณสามารถเพิ่มการเข้ารหัสพารามิเตอร์ที่สามเพื่อให้แน่ใจว่าประเภทการเข้ารหัสคือ 'utf-8'

หมายเหตุ: วิธีนี้ใช้ได้ดีใน Python3 ฉันไม่ได้ลองใน Python2.7


ใช้ไม่ได้ใน Python 2.7.10:TypeError: 'encoding' is an invalid keyword argument for this function
Borhan Kazimipour

2
ไม่ทำงานใน Python 2.7.10: ใช้TypeError: 'encoding' is an invalid keyword argument for this function งานได้ดี:import io with io.open(file_path, 'r', encoding="utf-8") as f: for line in f: do_something(line)
Borhan Kazimipour

2
ทำงานได้อย่างมีเสน่ห์ใน python3.6 ขอบคุณมาก!
SRC

32

สำหรับฉันมีปัญหากับการเข้ารหัสเทอร์มินัล การเพิ่ม UTF-8 ไปที่. bashrc ช่วยแก้ปัญหาได้:

export LC_CTYPE=en_US.UTF-8

อย่าลืมโหลด. bashrc ใหม่ในภายหลัง:

source ~/.bashrc

3
ฉันต้องใช้export LC_ALL=C.UTF-8บน Ubuntu 18.04.3 และ Python 3.6.8 มิฉะนั้นสิ่งนี้จะช่วยแก้ปัญหาของฉันได้ขอบคุณ
jbaranski

31

คุณสามารถลองสิ่งนี้:

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

3
ความหมายของสิ่งนี้คืออะไร? ดูเหมือนจะเป็นสิ่งที่ใช้ได้ทั่วโลกและไม่เพียง แต่ใช้ได้กับไฟล์นี้เท่านั้น
simeg

2
โปรดสังเกตว่าข้างต้นเลิกใช้งานใน Python 3
gented

12

เมื่อใช้ Ubuntu 18.04 โดยใช้Python3.6ฉันได้แก้ไขปัญหาโดยทำทั้งสองอย่าง:

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

และหากคุณกำลังเรียกใช้เครื่องมือเป็นบรรทัดคำสั่ง:

export LC_ALL=C.UTF-8

โปรดทราบว่าหากคุณอยู่ในPython2.7คุณต้องจัดการสิ่งนี้แตกต่างออกไป ก่อนอื่นคุณต้องตั้งค่าการเข้ารหัสเริ่มต้น:

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

จากนั้นในการโหลดไฟล์คุณต้องใช้io.openเพื่อตั้งค่าการเข้ารหัส:

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

คุณยังต้องส่งออก env

export LC_ALL=C.UTF-8

7

ฉันได้รับข้อผิดพลาดนี้เมื่อพยายามติดตั้งแพ็คเกจ python ใน Docker container สำหรับฉันปัญหาคืออิมเมจนักเทียบท่าไม่ได้localeกำหนดค่าไว้ การเพิ่มรหัสต่อไปนี้ใน Dockerfile ช่วยแก้ปัญหาให้ฉันได้

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

ฉันต้องใช้สิ่งนี้: github.com/docker-library/python/issues/13
พฤษภาคม

4

หากต้องการค้นหาข้อผิดพลาด unicode ใด ๆ และทั้งหมดที่เกี่ยวข้อง ... ใช้คำสั่งต่อไปนี้:

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

พบของฉันใน

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

เมื่อใช้shedฉันพบลำดับการกระทำที่ไม่เหมาะสม กลายเป็นความผิดพลาดของบรรณาธิการ

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


0

สำหรับ python 3 การเข้ารหัสเริ่มต้นจะเป็น "utf-8" แนะนำขั้นตอนต่อไปนี้ในเอกสารพื้นฐาน: https://docs.python.org/2/library/csv.html#csv-examplesในกรณีที่เกิดปัญหาใด ๆ

  1. สร้างฟังก์ชัน

    def utf_8_encoder(unicode_csv_data):
        for line in unicode_csv_data:
            yield line.encode('utf-8')
  2. จากนั้นใช้ฟังก์ชันภายในเครื่องอ่านเช่น

    csv_reader = csv.reader(utf_8_encoder(unicode_csv_data))

0

python3x หรือสูงกว่า

  1. โหลดไฟล์ในไบต์สตรีม:

    body = '' สำหรับบรรทัดใน open ('website / index.html', 'rb'): decodedLine = lines.decode ('utf-8') body = body + decodedLine.strip () return body

  2. ใช้การตั้งค่าส่วนกลาง:

    นำเข้า io นำเข้า sys sys.stdout = io.TextIOWrapper (sys.stdout.buffer, การเข้ารหัส = 'utf-8')


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.