使用Python发邮件:传入文件读取的message变量收到空邮件
异常核心原因
你遇到的问题本质是文件读取的字符串存在肉眼不可见的结构偏差,触发了Gmail SMTP服务的严格内容解析规则,最终被判定为空正文,和硬编码测试的差异点主要集中在两方面:
- 文件读取的内容自带多余控制字符,打乱了SMTP协议的解析逻辑
readlines()方法读取的每一行内容,默认会保留文件行尾的换行、回车字符。你肉眼在终端打印内容时,这些控制字符只会触发普通的换行显示,很难被注意到,但Gmail的SMTP服务会按照固定规则解析传入的内容:协议规定连续两个换行(\r\n\r\n)是「邮件头部/正文」的分隔标记,分隔符之前的内容会被全部判定为邮件头部字段,分隔符之后的才是实际下发给收件人的正文。
如果从文件读出来的字符串刚好是「有效内容在前,连续两个换行紧跟在内容后面」的结构,就会出现“头部吞掉了全部有效内容、分隔符后面没有任何正文”的情况,收件人收到的自然就是空邮件,但你打印时只会看到内容正常显示,感知不到换行的位置偏差。
除此之外,文件存储时可能残留的不可见字符(比如空字节、BOM头、单独的回车符),也会干扰SMTP的行解析逻辑,让服务器把原本的有效正文判定为无效的协议控制信息,直接丢弃。 - 缺少标准邮件结构的兜底
硬编码测试时,单段纯文本没有触发上述解析边界问题,所以Gmail会把整段字符串直接当正文下发;但传入带结构偏差的文件读取内容时,没有标准邮件头部做格式锚定,服务器就会按照默认的解析规则拆分内容,最终出现空邮件。
可落地的修复方法
- 读取文件内容后做清洗处理:把原来的
message = line[0]改成message = line[0].strip(),去掉字符串首尾所有无意义的换行、回车、空白字符和不可见控制字符。 - 排查隐藏字符:对比硬编码测试字符串和文件读取字符串的
repr()输出,比如打印repr(message),就能直接看到肉眼不可见的隐藏字符,精确定位结构差异。 - 从根源上避免解析问题:不要直接把裸字符串传入
sendmail,用Python内置的email模块构造带标准头部(发件人、收件人、主题、正文)的合规邮件对象,让SMTP服务不需要靠猜规则拆分内容。
注意:Gmail的SMTP服务对非标准格式的邮件内容校验比其他服务商严格很多,裸字符串传参的容错率极低,哪怕一个多余的换行都可能导致内容解析异常。
内容的提问来源于stack exchange,提问作者user15446771
相关产品推荐
相关产品推荐

