UnicodeDecodeError: кодек "ascii" не может декодировать байт 0xd0 в позиции 8: порядковый номер не в диапазоне (128)

Я пытался написать программу на Python, которая считывает значения ячеек из файла Excel, переводит содержимое ячейки с эстонского на английский или русский и объединяет их в одну строку. Результаты печатаются в текстовый файл. Эстонский -> Английский, кажется, работает нормально, но с русским языком появляются ошибки:

Traceback (most recent call last):   
     File "erid.py", line 140, in <module>
      f.write(aNimed(row_index, 1, 'ru')+ '\n')
      File "erid.py", line 120, in aNimed
    nimi += komponendid[i].strip() 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 8: ordinal not in range(128)

 Traceback (most recent call last):
 File "erid.py", line 140, in <module>
     f.write(aNimed(row_index, 1, 'ru')+ '\n')   File "erid.py", line 120, in aNimed
     nimi = nimi + komponendid[i][1:].strip()
 UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 9: ordinal not in
 range(128)

Первый вызывается словом "antibakteriaalne", а второй - " + hoobkäepide". Я подозреваю, что знак "+" является причиной проблемы во втором случае, а не "ä". Некоторые русские символы кажутся проблемой, а некоторые нет. Я как бы вне идей.

Код Python:

# -*- coding: utf-8 -*-
from xlrd import open_workbook, cellname, XL_CELL_TEXT 
from xlwt import Workbook
from xlutils.copy import copy
import sonaraamatud #dictionary

# open file with data
book = open_workbook('Datafile.xls')
# Safe write unicode to ignore unicode errors
# http://developer.plone.org/troubleshooting/unicode.html
def safe_write(failName, word):
    if type(word) == str:
        failName.write(word + '\n')
    else:
        failName.write(word.decode("utf-8") + '\n')

def safeDecode(word):
    if type(word) == str:
        word = unicode(word, 'utf-8', errors='ignore')
        return word
    else:
        word = unicode(word)
        return word

# Translate surface coating name
def translatePind(langa, langb, word):
        answ = ""
        if (sonaraamatud.kasOlemas3(langa, sonaraamatud.pinnaKatted) == True):
                answ = langa
                return answ
        #if langa is Estonian
        if (langa == 'et'):
                # if langb is english
                if (langb == 'en'):
                        try:
                                answ = sonaraamatud.pinnakattedEstEng[word]
                        except KeyError:
                                answ = word
                # If lang b is russian
                elif (langb == "ru"):
                        try:
                                answ = sonaraamatud.pinnakattedEngRus[sonaraamatud.pinnakattedEstEng[word]]
                        except KeyError:
                                answ = word

        # if langa is english
        elif (langa == "en"):
                # if langb is Estonian
                if (langb == "et"):
                        try:
                                answ = sonaraamatud.pinnakattedEngEst[word]
                        except KeyError:
                                answ = word
                # if langb is Russian
                elif (langb == "ru"):
                        try:
                                answ = sonaraamatud.pinnakattedEngRus[word]
                        except KeyError:
                                answ = "KeyError"
        return answ

def aNimed(row, sheetNr, lang):
        #  Function combines name
        #  name: aNimed
        #  @param: rida, lehe number
        #  @return: Product name
        #vali leht (worksheet)
        sheet = book.sheet_by_index(sheetNr) #sheetNr
        komponendid = []
        nimi = ""
        if (lang == 'et'):
        komponendid.append(str(sheet.cell(row, 5).value)) # Model
                komponendid.append('(' + sheet.cell(row, 6).value + ')')#surface
                komponendid.append(sheet.cell(row, 7).value) #extras
        elif (lang == 'en'):
                komponendid.append(str(sheet.cell(row, 5).value)) # Mudel
                komponendid.append('(' + translatePind('et', 'en', sheet.cell(row, 6).value) + ')')
                komponendid.append(sheet.cell(row, 7).value) #lisad
        elif (lang == 'ru'):
                """
                Alternativ method trying to use safeDecode, NOT working! 
                komponendid.append(str(safeDecode(sheet.cell(row, 5).value))) # Mudel
                surface= safeDecode(sheet.cell(row, 6).value)
                komponendid.append('(' + translatePind('et', 'ru', str(surface)) + ')')
                komponendid.append(safeDecode(sheet.cell(row, 7).value)) #lisad
                """
                komponendid.append(str(sheet.cell(row, 5).value)) # Mudel
                komponendid.append('(' + translatePind('et', 'ru',sheet.cell(row, 6).value) + ')')
                komponendid.append(sheet.cell(row, 7).value) #lisad
        pikkus = len(komponendid)

        print(komponendid)
        for i in range(0, pikkus):
                if (komponendid[i] == "" or komponendid[i] == "()" or komponendid[i] == " "):
                        i+=1
                        continue
                elif (i == pikkus-1 and komponendid[i][0] != " "):
                        print("1"+ komponendid[i])
                        nimi += komponendid[i].strip()
                        i+=1
                elif (komponendid[i][0] == " " and komponendid[i][1]== "+"):
                        #print("2"+ komponendid[i])
                        nimi = nimi + komponendid[i][1:].strip()
                        i+=1
                else :
                        #print("4"+ komponendid[i])
                        nimi = nimi + komponendid[i].strip() + " "
                        i+=1
        return nimi

# Use: aNimed(row, sheetNr, lang)
sheet = book.sheet_by_index(7)
f= open('data.txt', 'w')
for row_index in range (1, sheet.nrows):
    #print(aNimed(row_index, 5, 'en'))
    f.write(aNimed(row_index, 1, 'ru')+ '\n')
    #safe_write(f, aNimed(row_index, 1, 'ru'))
f.close()

1 ответ

Это не особенно элегантно, но я думаю, что у меня есть обходной путь. Вместо чтения из файла Excel, читать из файла CSV. Например,

`import csv
data = []
opened_file = open(csv_filename, 'rb')
reader = csv.reader(opened_file)
for row in reader:
    data.append(row)
opened_file.close()`

Теперь ваши данные сохранены в виде списка. Сделайте перевод и сохраните его в другом списке, скажем так: translation_data. Теперь, и это ключ, вы можете открыть новую книгу с

`from xlwt import Workbook
book = Workbook(encoding="utf8")
foo = book.add_sheet("foo")
for row_num in range(len(translated_data)):
    for col_num in range(len(translated_data[row_num]):
        foo.write(row_num, col_num, translated_data[row_num][col_num]
book.save("filename.xls")`  

Ключ в том, что вы можете указать кодировку, если вы используете Workbook(), но если вы используете open_workbook(), похоже, что вы застряли в ascii.

Другие вопросы по тегам