【问题标题】:Batch Request for get in gmail API获取 gmail API 的批量请求
【发布时间】:2018-12-02 17:35:39
【问题描述】:

我有一个大约 2500 个邮件 ID 的列表,我坚持只使用请求库,到目前为止,我这样做是为了获取邮件标题

mail_ids = ['']
for mail_id in mails_ids:
    res = requests.get(
         'https://www.googleapis.com/gmail/v1/users/me/messages/{}? 
          format=metadata'.format(mail_id), headers=headers).json()
    mail_headers = res['payload']['headers']
    ...

但它的效率非常低,我宁愿发布 ID 列表,但在他们的文档 https://developers.google.com/gmail/api/v1/reference/users/messages/get 上,我没有看到 BatchGet,有什么解决方法吗?我正在使用 Flask 框架 非常感谢

【问题讨论】:

  • 你见过this answer吗?
  • @Tholle 是的,但他使用 google api 客户端,我不能,我需要坚持使用 requests lib
  • 好的。 This answerthis tiny JavaScript helper I wrote 可能会为如何自己手动创建批处理请求提供一些灵感,但遗憾的是,我没有 Python 示例。
  • 感谢@Tholle 的帮助,我会努力的:)

标签: gmail-api


【解决方案1】:

这有点晚了,但如果它可以帮助任何人,这是我用来批量获取电子邮件的代码:

  1. 首先,我得到一份相关电子邮件的列表。根据您的需要更改请求,我只会在特定时间段内收到发送的电子邮件:
query = "https://www.googleapis.com/gmail/v1/users/me/messages?labelIds=SENT&q=after:2020-07-25 before:2020-07-31"
response = requests.get(query, headers=header)
events = json.loads(response.content)
email_tokens = events['messages']
while 'nextPageToken' in events:
    response = requests.get(query+f"&pageToken={events['nextPageToken']}", 
                            headers=header)
    events = json.loads(response.content)
    email_tokens += events['messages']
  1. 然后我批量处理一次获取 100 封电子邮件的 get 请求,并仅解析电子邮件的 json 部分并将其放入名为 emails 的列表中。请注意,这里有一些重复的代码,因此您可能希望将其重构为一个方法。 您必须在此处设置访问令牌
emails = []
access_token = '1234'
header = {'Authorization': 'Bearer ' + access_token}
batch_header = header.copy()
batch_header['Content-Type'] = 'multipart/mixed; boundary="email_id"'
data = ''
ctr = 0
for token_dict in email_tokens:
    data += f'--email_id\nContent-Type: application/http\n\nGET /gmail/v1/users/me/messages/{token_dict["id"]}?format=full\n\n'
    if ctr == 99:
        data += '--email_id--'
        print(data)
        r = requests.post(f"https://www.googleapis.com/batch/gmail/v1", 
                          headers=batch_header, data=data)
        bodies = r.content.decode().split('\r\n')
        for body in bodies:
            if body.startswith('{'):
                parsed_body = json.loads(body)
                emails.append(parsed_body)
        ctr = 0
        data = ''
        continue
    ctr+=1
data += '--email_id--'
r = requests.post(f"https://www.googleapis.com/batch/gmail/v1", 
                  headers=batch_header, data=data)
bodies = r.content.decode().split('\r\n')
for body in bodies:
    if body.startswith('{'):
        parsed_body = json.loads(body)
        emails.append(parsed_body)
  1. [可选] 最后,我正在解码电子邮件中的文本并仅存储最后发送的电子邮件而不是整个线程。此处使用的正则表达式拆分字符串,我发现这些字符串通常位于电子邮件的末尾。例如,On Tue, Jun 23, 2020, x@gmail.com said...:
import re
import base64
gmail_split_regex = r'On [a-zA-z]{3}, ([a-zA-z]{3}|\d{2}) ([a-zA-z]{3}|\d{2}),? \d{4}'

for email in emails:
    if 'parts' not in email['payload']:
        continue
    for part in email['payload']['parts']:
        if part['mimeType'] == 'text/plain':
            if 'uniqueBody' not in email:
                plainText = str(base64.urlsafe_b64decode(bytes(str(part['body']['data']), encoding='utf-8')))
                email['uniqueBody'] = {'content': re.split(gmail_split_regex, plainText)[0]}
        elif 'parts' in part:
            for sub_part in part['parts']:
                if sub_part['mimeType'] == 'text/plain':
                    if 'uniqueBody' not in email:
                        plainText = str(base64.urlsafe_b64decode(bytes(str(sub_part['body']['data']), encoding='utf-8')))
                        email['uniqueBody'] = {'content': re.split(gmail_split_regex, plainText)[0]}

【讨论】:

    猜你喜欢
    • 2018-05-21
    • 2018-07-27
    • 2019-08-24
    • 2017-12-09
    • 2020-06-11
    • 2020-02-24
    • 2017-10-27
    • 1970-01-01
    • 2015-04-22
    相关资源
    最近更新 更多