Python发送Quoted-Printable编码邮件接收端未解码问题求助
Python email库新版API设置Quoted-Printable编码后邮件无法解码问题排查
问题描述
使用Python的email库新版API发送邮件,设置CTE为Quoted-Printable,但接收端无法解码邮件正文,查看原始邮件时内容仍处于编码状态。同时自定义HTML头部的meta标签里,“http”与“equiv”之间的短横线显示为编码状态,希望发送支持完整UTF-8的邮件,当前用smtplib的send_message(msg)方法发送。
现有代码
打包EmailMessage的代码
""" @type sndr: str @type rcvr: str @type subj: str @type body: tuple @type extra: tuple @return: bytes """ msg = message.EmailMessage() if '<' in sndr: name, sep, addr = sndr.rpartition(' ') # Partition at space between display name & address name = name.strip() # Remove leading and trailing spaces addr = addr.strip('<>') # Remove leading and trailing angle brackets msg['From'] = headerregistry.Address(display_name=name, addr_spec=addr) else: msg['From'] = headerregistry.Address(display_name='', addr_spec=sndr) if '<' in rcvr: name, sep, addr = rcvr.rpartition(' ') name = name.strip() addr = addr.strip('<>') msg['To'] = headerregistry.Address(display_name=name, addr_spec=addr) else: msg['To'] = headerregistry.Address(display_name='', addr_spec=rcvr) msg['Subject'] = subj msg.set_content(body[0], charset='utf-8') msg.add_alternative(body[1], cte='quoted-printable', subtype='html') return msg
HTML正文生成代码
""" @type body: str @return: str """ first = \ '<html><head>\r' \ '<meta http–equiv="Content-Type" content="text/html; charset=utf-8">\r' \ '</head>' second = f'<body><div>{body}</div></body></html>' payload = first + second return payload
问题排查与解决方案
1. 特殊符号导致编码异常
自定义meta标签里的http–equiv使用了全角破折号(–),而非标准半角短横线(-)。这个非ASCII字符会被Quoted-Printable编码,导致显示异常,替换为半角短横线即可解决。
2. 字符集声明缺失
调用add_alternative时未明确指定charset='utf-8',导致邮件内容的字符集未被正确绑定,接收端无法识别解码规则,需在方法参数中补充该配置。
3. 冗余meta标签冲突
手动添加的meta标签容易和email库自动生成的标签冲突,库会根据charset参数自动生成标准的Content-Type meta标签,无需手动编写,移除手动标签即可避免冲突。
修正后的代码
打包EmailMessage的代码
""" @type sndr: str @type rcvr: str @type subj: str @type body: tuple @type extra: tuple @return: bytes """ import email.message import email.headerregistry msg = email.message.EmailMessage() if '<' in sndr: name, sep, addr = sndr.rpartition(' ') # Partition at space between display name & address name = name.strip() # Remove leading and trailing spaces addr = addr.strip('<>') # Remove leading and trailing angle brackets msg['From'] = email.headerregistry.Address(display_name=name, addr_spec=addr) else: msg['From'] = email.headerregistry.Address(display_name='', addr_spec=sndr) if '<' in rcvr: name, sep, addr = rcvr.rpartition(' ') name = name.strip() addr = addr.strip('<>') msg['To'] = email.headerregistry.Address(display_name=name, addr_spec=addr) else: msg['To'] = email.headerregistry.Address(display_name='', addr_spec=rcvr) msg['Subject'] = subj msg.set_content(body[0], charset='utf-8') # 明确指定charset,让库自动处理编码和meta标签 msg.add_alternative(body[1], cte='quoted-printable', subtype='html', charset='utf-8') return msg
HTML正文生成代码
""" @type body: str @return: str """ # 移除手动meta标签,由email库自动生成 payload = f'<html><head></head><body><div>{body}</div></body></html>' return payload
补充说明
send_message方法会自动处理邮件的编码传输,只要邮件对象配置正确,接收端就能正常解码Quoted-Printable格式的内容。- 确保HTML内容中仅使用ASCII范围内的符号,避免非必要的特殊字符被编码。
内容的提问来源于stack exchange,提问作者malonn
相关产品推荐
相关产品推荐

