UnicodeDecodeError: кодек utf-8 не может декодировать байт 0x80 при загрузке файла рассола с использованием pydrive в google colaboratory

Я новичок в использовании google colaboratory (colab) и pydrive вместе с ним. Я пытаюсь загрузить данные в 'CAS_num_strings', которые были записаны в файле pickle в определенном каталоге на моем диске Google, используя colab как:

pickle.dump(CAS_num_strings,open('CAS_num_strings.p', 'wb'))
dump_meta = {'title': 'CAS.pkl', 'parents': [{'id':'1UEqIADV_tHic1Le0zlT25iYB7T6dBpBj'}]} 
pkl_dump = drive.CreateFile(dump_meta)
pkl_dump.SetContentFile('CAS_num_strings.p')
pkl_dump.Upload()
print(pkl_dump.get('id'))

Где 'id': '1UEqIADV_tHic1Le0zlT25iYB7T6dBpBj' гарантирует, что у него есть конкретная родительская папка с этим идентификатором. Последняя команда печати дает мне результат:

'1ZgZfEaKgqGnuBD40CY8zg0MCiqKmi1vH'

Следовательно, я могу создать и выгрузить файл рассола с идентификатором 1ZgZfEaKgqGnuBD40CY8zg0MCiqKmi1vH. Теперь я хочу загрузить этот файл рассола в другой скрипт colab для другой цели. Для загрузки я использую набор команд:

cas_strings = drive.CreateFile({'id':'1ZgZfEaKgqGnuBD40CY8zg0MCiqKmi1vH'})
print('title: %s, mimeType: %s' % (cas_strings['title'], cas_strings['mimeType']))
print('Downloaded content "{}"'.format(cas_strings.GetContentString()))

Это дает мне результат:

title: CAS.pkl, mimeType: text/x-pascal

---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-9-a80d9de0fecf> in <module>()
     30 cas_strings = drive.CreateFile({'id':'1ZgZfEaKgqGnuBD40CY8zg0MCiqKmi1vH'})
     31 print('title: %s, mimeType: %s' % (cas_strings['title'], cas_strings['mimeType']))
---> 32 print('Downloaded content "{}"'.format(cas_strings.GetContentString()))
     33 
     34 

/usr/local/lib/python3.6/dist-packages/pydrive/files.py in GetContentString(self, mimetype, encoding, remove_bom)
    192                     self.has_bom == remove_bom:
    193       self.FetchContent(mimetype, remove_bom)
--> 194     return self.content.getvalue().decode(encoding)
    195 
    196   def GetContentFile(self, filename, mimetype=None, remove_bom=False):

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte

Как видите, он находит файл CAS.pkl, но не может декодировать данные. Я хочу исправить эту ошибку. Я понимаю, что нормальное кодирование / декодирование utf-8 работает плавно во время обычного сброса и загрузки рассола с параметрами 'wb' и 'rb'. Однако в данном случае после сброса я не могу загрузить его из файла рассола на диске Google, созданного на предыдущем шаге. Ошибка существует где-то во мне, я не могу указать, как декодировать данные в «return self.content.getvalue (). Decode (encoding)». Я не могу найти отсюда (https://developers.google.com/drive/v2/reference/files#resource-presentations), какие ключевые слова / теги метаданных нужно изменить. Любая помощь приветствуется. Спасибо


person Abhishek S Khetan    schedule 07.03.2018    source источник
comment
Я вижу, вы вызываете pickle.dump, но никогда не вызывали pickle.load - может ли быть проблема?   -  person Robin Davis    schedule 07.03.2018
comment
неплохо подмечено. Я хочу попробовать именно это, но не могу понять, где в последовательности будет работать pydrive. он не может работать без использования pydrive в сочетании, потому что только pydrive может извлекать файлы по их идентификатору с диска Google   -  person Abhishek S Khetan    schedule 07.03.2018


Ответы (2)


Проблема в том, что GetContentString работает, только если содержимое является допустимой строкой UTF-8 (docs), а ваш рассол - нет.

К сожалению, вам придется проделать небольшую дополнительную работу, поскольку нет GetContentBytes - вам нужно сохранить содержимое в файл и прочитать его обратно. Вот рабочий пример: https://colab.research.google.com/drive_Ygmh21OrX28KY0Dv9 а>

person Craig Citro    schedule 08.03.2018
comment
Спасибо, мой ответ почти такой же, как и ваш! - person Abhishek S Khetan; 08.03.2018

На самом деле, я нашел элегантный ответ с небольшой помощью моих друзей. Вместо GetContentStrings я использую GetContentFile, который является аналогом SetContentFile. Это загружает файл в текущую рабочую область, из которой я могу читать его, как любой файл рассола. Наконец, данные хорошо загружаются в cas_nums.

cas_strings = drive.CreateFile({'id':'1ZgZfEaKgqGnuBD40CY8zg0MCiqKmi1vH'})
print('title: %s, mimeType: %s' % (cas_strings['title'], cas_strings['mimeType']))
cas_strings.GetContentFile(cas_strings['title'])
cas_nums = pickle.load(open(cas_strings['title'],'rb'))

Более подробную информацию об этом можно найти в документации pydrive в разделе «Загрузка содержимого файла» - http://pythonhosted.org/PyDrive/filemanagement.html#download-file-content

person Abhishek S Khetan    schedule 08.03.2018