You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Gmail API读取邮件触发'parts'错误的排查咨询

解决Gmail API读取邮件时的'parts'错误

错误原因

你遇到的'parts'错误,核心原因是并非所有邮件的payload都包含parts字段:

  • 纯文本格式的邮件,payload里没有parts,直接通过payload['body']存储内容
  • 带附件/多格式的邮件(比如同时有HTML和纯文本)才会有parts数组
    和邮件语种、是否包含图片没有直接关系,只是这类邮件更可能是多格式结构,而纯文本邮件触发了无parts的情况

修复后的代码

修改代码,先判断payload是否存在parts,再分别处理:

import base64
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

SCOPES = ['https://www.googleapis.com/auth/gmail.readonly', 'https://www.googleapis.com/auth/gmail.modify']

try:
    # Call the Gmail API
    service = build('gmail', 'v1', credentials=creds)
    results = service.users().messages().list(userId='me', labelIds=['INBOX']).execute()
    messages = results.get('messages', [])

    if not messages:
        print('No messages found.')
    else:
        for message in messages:
            msg = service.users().messages().get(userId='me', id=message['id'], format='full').execute()
            # 获取发件人
            from_name = None
            for header in msg['payload']['headers']:
                if header['name'] == 'From':
                    from_name = header['value']
                    break
            
            # 处理邮件内容
            def extract_body(payload):
                if 'parts' in payload:
                    # 遍历多部分内容,优先取纯文本
                    for part in payload['parts']:
                        if part['mimeType'] == 'text/plain':
                            if 'data' in part['body']:
                                data = part['body']['data']
                                byte_code = base64.urlsafe_b64decode(data)
                                return byte_code.decode('utf-8', errors='replace')
                        # 递归处理嵌套的parts(比如multipart/alternative里的子部分)
                        elif part['mimeType'].startswith('multipart/'):
                            nested_text = extract_body(part)
                            if nested_text:
                                return nested_text
                else:
                    # 纯文本邮件直接取body
                    if 'data' in payload['body']:
                        data = payload['body']['data']
                        byte_code = base64.urlsafe_b64decode(data)
                        return byte_code.decode('utf-8', errors='replace')
                return '无法提取邮件内容'
            
            email_text = extract_body(msg['payload'])
            print(f'邮件来自: {from_name} - 内容: {email_text}')

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

关键改进点

  • 新增extract_body函数,递归处理邮件的嵌套结构(比如multipart类型的邮件)
  • 优先提取text/plain类型内容,避免HTML格式干扰
  • 用decode('utf-8', errors='replace')处理非英文编码邮件,防止解码失败
  • 先判断parts是否存在再遍历,避免KeyError
  • 优化发件人获取逻辑,找到后直接终止循环,减少不必要的遍历

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:32:19