![](/img/trans.png)
[英]Download google drive attachments of an email using Gmail API in python
[英]Download Attachments from gmail using Gmail API
我正在使用 Gmail API 訪問我的 gmail 數據和 google python api 客戶端。
根據獲取消息附件的文檔,他們為python提供了一個示例
https://developers.google.com/gmail/api/v1/reference/users/messages/attachments/get
但是我嘗試了相同的代碼然后我收到錯誤:
AttributeError: 'Resource' object has no attribute 'user'
我收到錯誤的行:
message = service.user().messages().get(userId=user_id, id=msg_id).execute()
所以我通過替換user()
嘗試了users()
user()
message = service.users().messages().get(userId=user_id, id=msg_id).execute()
但我沒有讓part['body']['data']
for part in message['payload']['parts']
擴展@Eric 答案,我從文檔中編寫了以下更正版本的 GetAttachments 函數:
# based on Python example from
# https://developers.google.com/gmail/api/v1/reference/users/messages/attachments/get
# which is licensed under Apache 2.0 License
import base64
from apiclient import errors
def GetAttachments(service, user_id, msg_id):
"""Get and store attachment from Message with given id.
:param service: Authorized Gmail API service instance.
:param user_id: User's email address. The special value "me" can be used to indicate the authenticated user.
:param msg_id: ID of Message containing attachment.
"""
try:
message = service.users().messages().get(userId=user_id, id=msg_id).execute()
for part in message['payload']['parts']:
if part['filename']:
if 'data' in part['body']:
data = part['body']['data']
else:
att_id = part['body']['attachmentId']
att = service.users().messages().attachments().get(userId=user_id, messageId=msg_id,id=att_id).execute()
data = att['data']
file_data = base64.urlsafe_b64decode(data.encode('UTF-8'))
path = part['filename']
with open(path, 'w') as f:
f.write(file_data)
except errors.HttpError, error:
print 'An error occurred: %s' % error
您仍然可以通過關注@Ilya V. Schurov或@Cam T 的回答來錯過附件,原因是電子郵件結構可能因mimeType
而異。
import base64
from apiclient import errors
def GetAttachments(service, user_id, msg_id, store_dir=""):
"""Get and store attachment from Message with given id.
Args:
service: Authorized Gmail API service instance.
user_id: User's email address. The special value "me"
can be used to indicate the authenticated user.
msg_id: ID of Message containing attachment.
store_dir: The directory used to store attachments.
"""
try:
message = service.users().messages().get(userId=user_id, id=msg_id).execute()
parts = [message['payload']]
while parts:
part = parts.pop()
if part.get('parts'):
parts.extend(part['parts'])
if part.get('filename'):
if 'data' in part['body']:
file_data = base64.urlsafe_b64decode(part['body']['data'].encode('UTF-8'))
#self.stdout.write('FileData for %s, %s found! size: %s' % (message['id'], part['filename'], part['size']))
elif 'attachmentId' in part['body']:
attachment = service.users().messages().attachments().get(
userId=user_id, messageId=message['id'], id=part['body']['attachmentId']
).execute()
file_data = base64.urlsafe_b64decode(attachment['data'].encode('UTF-8'))
#self.stdout.write('FileData for %s, %s found! size: %s' % (message['id'], part['filename'], attachment['size']))
else:
file_data = None
if file_data:
#do some staff, e.g.
path = ''.join([store_dir, part['filename']])
with open(path, 'w') as f:
f.write(file_data)
except errors.HttpError as error:
print 'An error occurred: %s' % error
我測試了上面的代碼並且不起作用。 我為其他帖子更新了一些東西。 寫文件錯誤
import base64
from apiclient import errors
def GetAttachments(service, user_id, msg_id, prefix=""):
"""Get and store attachment from Message with given id.
Args:
service: Authorized Gmail API service instance.
user_id: User's email address. The special value "me"
can be used to indicate the authenticated user.
msg_id: ID of Message containing attachment.
prefix: prefix which is added to the attachment filename on saving
"""
try:
message = service.users().messages().get(userId=user_id, id=msg_id).execute()
for part in message['payload'].get('parts', ''):
if part['filename']:
if 'data' in part['body']:
data=part['body']['data']
else:
att_id=part['body']['attachmentId']
att=service.users().messages().attachments().get(userId=user_id, messageId=msg_id,id=att_id).execute()
data=att['data']
file_data = base64.urlsafe_b64decode(data.encode('UTF-8'))
path = prefix+part['filename']
with open(path, 'wb') as f:
f.write(file_data)
except errors.HttpError as error:
print('An error occurred: %s' % error)
這絕對是“用戶()”。 響應消息的格式很大程度上取決於您使用的格式參數。 如果您使用默認值 (FULL),那么部分將具有 part['body']['data'] 或者,當數據很大時,帶有可以傳遞給 messages().attachments() 的“attachment_id”字段。得到()。
如果您查看附件文檔,您會看到: https : //developers.google.com/gmail/api/v1/reference/users/messages/attachments
(如果在主消息文檔頁面上也提到了這一點,那就太好了。)
我對上面的代碼進行了以下更改,並且對於包含附件文檔的每個電子郵件 ID 都完全正常,我希望這可以有所幫助,因為使用 API 示例您將收到錯誤密鑰。
def GetAttachments(service, user_id, msg_id, store_dir):
"""Get and store attachment from Message with given id.
Args:
service: Authorized Gmail API service instance.
user_id: User's email address. The special value "me"
can be used to indicate the authenticated user.
msg_id: ID of Message containing attachment.
prefix: prefix which is added to the attachment filename on saving
"""
try:
message = service.users().messages().get(userId=user_id, id=msg_id).execute()
for part in message['payload']['parts']:
newvar = part['body']
if 'attachmentId' in newvar:
att_id = newvar['attachmentId']
att = service.users().messages().attachments().get(userId=user_id, messageId=msg_id, id=att_id).execute()
data = att['data']
file_data = base64.urlsafe_b64decode(data.encode('UTF-8'))
print(part['filename'])
path = ''.join([store_dir, part['filename']])
f = open(path, 'wb')
f.write(file_data)
f.close()
except errors.HttpError, error:
print 'An error occurred: %s' % error
感謝@Ilya V. Schurov和@Todor提供答案。 如果同一搜索字符串有帶附件和不帶附件的郵件,您仍然可能會錯過郵件。 這是我為兩種類型的郵件(即帶附件和不帶附件)獲取郵件正文的方法。
def get_attachments(service, msg_id):
try:
message = service.users().messages().get(userId='me', id=msg_id).execute()
for part in message['payload']['parts']:
if part['filename']:
if 'data' in part['body']:
data = part['body']['data']
else:
att_id = part['body']['attachmentId']
att = service.users().messages().attachments().get(userId='me', messageId=msg_id,id=att_id).execute()
data = att['data']
file_data = base64.urlsafe_b64decode(data.encode('UTF-8'))
path = part['filename']
with open(path, 'wb') as f:
f.write(file_data)
except errors.HttpError as error:
print ('An error occurred: %s') % error
def get_message(service,msg_id):
try:
message = service.users().messages().get(userId='me', id=msg_id).execute()
if message['payload']['mimeType'] == 'multipart/mixed':
for part in message['payload']['parts']:
for sub_part in part['parts']:
if sub_part['mimeType'] == 'text/plain':
data = sub_part['body']['data']
break
if data:
break
else:
for part in message['payload']['parts']:
if part['mimeType'] == 'text/plain':
data = part['body']['data']
break
content = base64.b64decode(data).decode('utf-8')
print(content)
return content
except errors.HttpError as error:
print("An error occured : %s") %error
from __future__ import print_function
import base64
import os.path
import oauth2client
from googleapiclient.discovery import build
from oauth2client import file,tools
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
store_dir=os.getcwd()
def attachment_download():
store = oauth2client.file.Storage('credentials_gmail.json')
creds = store.get()
if not creds or creds.invalid:
flow = oauth2client.client.flow_from_clientsecrets('client_secrets.json', SCOPES)
creds = oauth2client.tools.run_flow(flow, store)
try:
service = build('gmail', 'v1', credentials=creds)
results = service.users().messages().list(userId='me', labelIds=['XXXX']).execute() # XXXX is label id use INBOX to download from inbox
messages = results.get('messages', [])
for message in messages:
msg = service.users().messages().get(userId='me', id=message['id']).execute()
for part in msg['payload'].get('parts', ''):
if part['filename']:
if 'data' in part['body']:
data = part['body']['data']
else:
att_id = part['body']['attachmentId']
att = service.users().messages().attachments().get(userId='me', messageId=message['id'],id=att_id).execute()
data = att['data']
file_data = base64.urlsafe_b64decode(data.encode('UTF-8'))
filename = part['filename']
print(filename)
path = os.path.join(store_dir + '\\' 'Downloaded files' + '\\' + filename)
with open(path, 'wb') as f:
f.write(file_data)
f.close()
except Exception as error:
print(error)
請參閱:獲取標簽 ID https://developers.google.com/gmail/api/v1/reference/users/labels/list
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.