求助:原本正常的邮件内容打印代码突发AttributeError: 'NoneType'对象无'get_payload'属性错误
解决AttributeError: 'NoneType' object has no attribute 'get_payload' 邮件打印问题
Hey there, let's break down this error and fix it step by step!
错误原因拆解
This AttributeError means message.text_part is returning None—the PyzMessage object couldn't find a plain-text version of the email body. This usually happens for one of two reasons:
- The email you're fetching only has an HTML body (no plain-text alternative), so the
text_partproperty doesn't exist. - The email has a complex nested MIME structure that the
text_partshortcut can't automatically parse correctly.
修复方案
Let's adjust your code to handle these cases gracefully, with fallbacks for when plain-text content isn't available:
基础修复:检查text_part并添加HTML fallback
imapObj = imapclient.IMAPClient('outlook.office365.com', ssl=True) # Access IMAP server imapObj.login('EMAIL@XYZ.COM', 'PASSWORD') # Credential logins imapObj.select_folder('INBOX', readonly=False) UIDs = imapObj.search(['FROM' , 'EMAIL@XYZ.COM']) for i in UIDs: data = imapObj.fetch(i, ['BODY[]']) message = pyzmail.PyzMessage.factory(data[i][b'BODY[]']) # First check for plain-text content if message.text_part: print(f"=== Email UID {i} (Plain Text) ===") print(message.text_part.get_payload().decode(message.text_part.charset)) # Fall back to HTML if plain-text doesn't exist elif message.html_part: print(f"=== Email UID {i} (HTML) ===") print(message.html_part.get_payload().decode(message.html_part.charset)) # Handle cases where no body is found else: print(f"=== Email UID {i} ===") print("No readable body content found (check if this is an empty or non-standard email)")
进阶处理:手动遍历MIME部分(应对复杂邮件结构)
If some emails have nested multi-part structures that text_part misses, you can recursively scan all MIME parts to find the plain-text section:
imapObj = imapclient.IMAPClient('outlook.office365.com', ssl=True) imapObj.login('EMAIL@XYZ.COM', 'PASSWORD') imapObj.select_folder('INBOX', readonly=False) UIDs = imapObj.search(['FROM' , 'EMAIL@XYZ.COM']) def get_plain_text_body(message): # Recursively search for plain-text parts in nested MIME structures if message.is_multipart(): for part in message.parts: result = get_plain_text_body(part) if result: return result else: if message.get_content_type() == 'text/plain': return message.get_payload().decode(message.charset) return None for i in UIDs: data = imapObj.fetch(i, ['BODY[]']) message = pyzmail.PyzMessage.factory(data[i][b'BODY[]']) plain_text = get_plain_text_body(message) if plain_text: print(f"=== Email UID {i} ===") print(plain_text) elif message.html_part: print(f"=== Email UID {i} (HTML) ===") print(message.html_part.get_payload().decode(message.html_part.charset)) else: print(f"Email UID {i} has no readable body")
额外排查建议
- To debug specific problematic emails, print the full MIME structure with
print(message.parts)—this will show you all content blocks in the email, so you can see exactly what types are available. - Manually open the email in your Outlook client to confirm if it actually has a plain-text body (some senders only send HTML-formatted emails).
内容的提问来源于stack exchange,提问作者Alani
相关产品推荐
相关产品推荐

