Python3使用smtplib发邮件遇501行过长错误的解决咨询
解决SMTPDataError(501, 'Syntax error - line too long')问题
问题场景
在Python3环境下使用smtplib库发送邮件时,仅在添加附件(哪怕是不到1MB的图片)或HTML内容过长的情况下,会触发SMTPDataError错误,错误码501,提示信息为“Syntax error - line too long”。
代码示例
# MSG building msg = MIMEMultipart("alternative") msg.attach(MIMEText(email_text, "plain")) msg.attach(MIMEText(email_html, "html")) msg["To"] = to_email msg["From"] = from_email msg["Subject"] = subject msg["Date"] = formatdate() msg["Message-ID"] = make_msgid(domain=sender_domain) with open(attachment_dir, 'rb') as f: part = MIMEBase("application", "octet-stream") part.set_payload(f.read()) # Encode to Base64 encoders.encode_base64(part) # Set mail headers part.add_header( "Content-Disposition", "attachment", filename=attachment_name ) msg.attach(part) # Python 3 libraries expect bytes. msg_data = msg.as_bytes() # Create secure connection with server and send email context = ssl.create_default_context() with smtplib.SMTP_SSL("smtp.ionos.co.uk", 465, context=context) as mailserver: mailserver.login(from_email, from_password) mailserver.sendmail(from_email, to_email, msg_data)
报错回溯
Traceback (most recent call last): File "/home/server/repos/mailsender/run.py", line 33, in <module> email.send() File "/home/server/repos/mailsender/main.py", line 139, in send mailserver.sendmail(from_email, to_email, msg_data) File "/usr/lib/python3.9/smtplib.py", line 892, in sendmail raise SMTPDataError(code, resp) smtplib.SMTPDataError: (501, b'Syntax error - line too long')
核心原因
SMTP协议(RFC 2045)要求邮件内容的每行长度不得超过76个字符。当附件Base64编码后未按规范换行、或HTML文本未分段时,会出现单行过长的情况,触发服务器的语法错误。
语法层面解决方法
1. 规范附件的Base64编码换行
默认的encoders.encode_base64()可能存在换行不彻底的问题,手动对Base64编码后的内容按76字符分段换行:
import base64 # 替换原附件处理代码 with open(attachment_dir, 'rb') as f: part = MIMEBase("application", "octet-stream") # 读取文件并Base64编码 raw_data = f.read() b64_data = base64.b64encode(raw_data).decode('utf-8') # 每76字符插入换行符 wrapped_data = '\n'.join([b64_data[i:i+76] for i in range(0, len(b64_data), 76)]) part.set_payload(wrapped_data) # 设置必要头部 part.add_header("Content-Type", "application/octet-stream") part.add_header("Content-Transfer-Encoding", "base64") part.add_header( "Content-Disposition", "attachment", filename=attachment_name ) msg.attach(part)
2. 处理过长的HTML内容
对长HTML文本使用quoted-printable编码,自动拆分长行:
# 替换原HTML内容添加代码 html_part = MIMEText(email_html, "html", "utf-8") # 强制设置传输编码为quoted-printable html_part.replace_header('Content-Transfer-Encoding', 'quoted-printable') msg.attach(html_part)
3. 使用BytesGenerator生成合规邮件内容
替代msg.as_bytes(),用email.generator.BytesGenerator生成严格符合SMTP规范的邮件数据:
from email.generator import BytesGenerator from io import BytesIO # 生成合规的邮件字节流 buf = BytesIO() generator = BytesGenerator(buf, maxheaderlen=76) generator.flatten(msg, unixfrom=False) msg_data = buf.getvalue()
内容的提问来源于stack exchange,提问作者Mr Growbot
相关产品推荐
相关产品推荐

