Загрузить вложение из Gmail на Python: без ключа "данные"

Я использую официальные руководства Google для подключения к адресу Gmail и загрузки вложений из электронной почты с помощью Gmail API.

Приведенный пример кода выглядит следующим образом:

try:
    message = service.users().messages().get(userId=user_id, id=msg_id).execute()

    for part in message['payload']['parts']:
      if part['filename']:
        file_data = base64.urlsafe_b64decode(part['body']['data']
                                             .encode('UTF-8'))

        path = ''.join([store_dir, part['filename']])

        f = open(path, 'w')
        f.write(file_data)
        f.close()   

except errors.HttpError, error:
        print 'An error occurred: %s' % error

Я систематически получаю KeyError: «данные».

Когда я печатаю объект «часть», я получаю вот это. Я проверил, что все сообщения электронной почты содержат вложения, и вижу, что у ключа «body» есть поля «attachmentId» и «size», но нет поля «data».

{'partId': '1',
 'mimeType': 'application/x-zip-compressed',
 'filename': 'Statement.zip',
 'headers': [{'name': 'Content-Type', 'value': 'application/x-zip-compressed; name = "Statement.zip"'},
             {'name': 'Content-Description', 'value': 'Statement.zip'},
             {'name': 'Content-Disposition', 'value': 'attachment; filename = "Statement.zip"; size=317; creation-date = "Fri, 05 Oct 2018 11:00:24 GMT"; modification-date = "Fri, 05 Oct 2018 11:00:24 GMT"'},
             {'name': 'Content-Transfer-Encoding', 'value': 'base64'}],
 'body': {'attachmentId': 'ANGjdJ8Jsk95qxfAezayex3yDktM9hnMSwsy_LD4aqu3h2lhum36MT7pG9aqyWpX7VmNoxZISLAFfKyBy0gGgL5WyL5f7zrH4bRd_MBsHtGxXBfN6XBCg_qHkRu0ZVRaOtuYTCc8_aN4NMsaApGI19KJlfgVXV3w67gEspZ61OKZZwbt386wbA-_6GrAcQCGIgk4dFGxc_Zp5EjqIbsA557KOjEFoO0A9urMXIQvQXF0GRdhfHb287ZfhjKYGVpukhVxT6wDNjL47Ifc7VmG_kcgeUxpfKEGO6tmVw2PzuG4RlAdX5S7yjgGlEHGVmPgnTl-rjT7asZnia68cBg_5ATSJ9FS64OKcr79s8MQD-DL0omXLJjfw5-qIOUKM4x56btte572j5SO7afAYrsv',
          'size': 317}}

Поэтому я не получаю то же содержание, что и официальная документация Google. Я что-то упускаю? Как мне скачать вложение?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
6
0
1 374
2

Ответы 2

На вашей седьмой строке вы используете part['body']['data']. Однако в той части, которую вы печатаете, 'body' не имеет ключа 'data'. В нем есть только 'attachmentId' и 'size'.

да. Это мой вопрос. В документации используется поле данных, я не вижу этого поля, как мне скачать вложение?

Alexis Eggermont 11.10.2018 14:49

Я не уверен на 100%, но может ли это быть service.users (). Messages (). Attachment (). Get (userId, messageId, attId) .execute ()?

DanDeg 11.10.2018 14:54

@DanDeg, привет, как ты пришел к этому решению?

itsPav 17.06.2019 15:06

Нашел другой синтаксис, который работает:

  try:
    message = service.users().messages().get(userId=user_id, id=msg_id).execute()

    for part in message['payload']['parts']:
      if part['filename']:        
        attachment = service.users().messages().attachments().get(userId='me', messageId=message['id'], id=part['body']['attachmentId']).execute()
        file_data = base64.urlsafe_b64decode(attachment['data'].encode('UTF-8'))

        path = ''.join([store_dir, part['filename']])

        f = open(path, 'wb')
        f.write(file_data)
        f.close()

  except errors.HttpError as error:
    print(f'An error occurred: {error}')

Хорошая вещь. Документация до сих пор не обновляется.

itsPav 17.06.2019 14:54

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