Gmail API获取邮件时部分正文body返回size为0问题
根本原因
你读错了正文的存储位置,Gmail API对不同结构的邮件,正文存放路径不一样:
- 只有结构最简单的单部分邮件(比如纯文本无附件、单段HTML无其他资源的邮件),正文才会直接存在
payload.body.data字段里,也就是你成功读取的第二封邮件的情况。 - 剩下两封返回
{'size': 0}的都是多部分MIME结构邮件——你测试用的三封分别是Medium技术订阅邮件、电商营销邮件、问答平台订阅邮件,这类商用/订阅邮件为了兼容不同客户端,一般会同时打包纯文本、HTML两个版本的正文,部分还会内嵌图片、附加营销资源,这类邮件的顶层payload.body本身就是空占位符,所有实际正文内容都拆分存储在payload.parts数组的子块中,结构复杂的邮件还会出现多层嵌套的子parts,你只读取顶层body自然拿不到内容。
你能正常读取所有邮件的headers是因为不管什么结构的邮件,头信息都统一放在顶层payload.headers字段下,和正文的存储逻辑完全独立,和接口是否返回内容没有关系。
修复方案
不要直接读取payload.body,写个递归函数遍历所有part块,匹配正文类型提取内容即可,参考实现:
import base64 def extract_plain_text(payload): text_content = "" # 先检查当前层级是否存在有效正文 current_body = payload.get("body", {}) if current_body.get("data"): # Gmail返回的正文是URL安全的base64编码,需要解码 text_content = base64.urlsafe_b64decode(current_body["data"]).decode("utf-8", errors="ignore") # 遍历所有子块,嵌套结构递归处理 parts = payload.get("parts", []) for part in parts: # 跳过带文件名的附件块 if part.get("filename"): continue # 优先提取纯文本正文,适合做摘要场景 if part.get("mimeType") == "text/plain" and part.get("body", {}).get("data"): text_content = base64.urlsafe_b64decode(part["body"]["data"]).decode("utf-8", errors="ignore") break # 子块如果还有嵌套结构,递归查找 if part.get("parts"): sub_text = extract_plain_text(part) if sub_text: text_content = sub_text break return text_content
调用时直接把你拿到的content(即接口返回的payload对象)传入函数即可,不需要额外调整接口请求参数,保持format="full"的配置就行,比拉取raw格式自己解析MIME结构省事很多。
内容的提问来源于stack exchange,提问作者lillee205
相关产品推荐
相关产品推荐

