为什么有些 Python smtplib 邮件会传送到 Gmail 垃圾邮件文件夹?

Why do some Python smtplib messages deliver to Gmail spam folder?

我有个奇怪的问题。当我在我的脚本中使用 send_email1 函数发送消息时,消息最终进入我的 Gmail 垃圾邮件文件夹,但是当我使用 send_email2 时,它会成功发送到我的收件箱。第二条消息使用旧版 API,我认为它会在某个时候被弃用,我不应该再使用它了。

非常感谢您的帮助。

import smtplib
from email.message import EmailMessage
from email.mime.text import MIMEText


def send_email1(subject: str, content: str):

    msg = EmailMessage()
    msg['From'] = sender
    msg['To'] = recipient
    msg['Subject'] = subject
    msg.set_content(content)

    with smtplib.SMTP('mysmtpserver') as s:
        s.starttls()
        s.send_message(msg)


def send_email2(subject: str, content: str):

    msg = MIMEText(content)
    msg['Subject'] = subject
    msg['From'] = sender
    msg['To'] = recipient

    with smtplib.SMTP('mysmtpserver') as s:
        s.starttls()
        s.send_message(msg)


sender = 'sender@abc.com'
recipient = 'Recipient <recipient@abc.com>'

send_email1("Test message from Pyton1", "Test message from Python script. 1")
send_email2("Test message from Pyton2", "Test message from Python script. 2")

Gmail 控制将哪些电子邮件发送到收件箱或垃圾邮件。 Google 对哪些电子邮件是垃圾邮件,哪些不是垃圾邮件进行了各种数据收集和分析。这似乎是 google 将一种内容类型视为垃圾邮件,而另一种则不是。

归根结底,这不是您从 python 发送邮件的方式,而是您放入邮件的内容(以及发送位置、内容类型、附件等其他内容)google 将决定是否将电子邮件发送到垃圾邮件。

例如,如果我发送一封包含“Catchup”的邮件以及我们有一段时间没说话的正文。 Google 可能会将它发送到我的收件箱。但是,如果我发送一封带有“单击此 LINK 以赢得 1 亿”的电子邮件,它可能会被放入垃圾邮件中。这不是您发送邮件的方式。它是邮件的内容及其属性。

查看结果 mail-data,两者均符合 RFC 5322,可以识别出两个差异:

From: sender@abc.com
To: Recipient <recipient@abc.com>
Subject: Test message from Pyton1
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
MIME-Version: 1.0

Test message from Python script. 1

Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: Test message from Pyton2
From: sender@abc.com
To: Recipient <recipient@abc.com>

Test message from Python script. 2

第一个区别是顺序。未在 spam-folder 中结束的邮件首先声明 header-fields Content-TypeMIME-Version。其次,指定的字符集是 charset="us-ascii" 相对于 utf-8.

虽然我们只能推测 G​​mail 的垃圾邮件过滤规则,但我建议 更改设置内容的顺序和header-fields以及 使用

明确说明 Content-Type(及其子类型和字符集)

msg.set_content(content, subtype="plain", charset='us-ascii')

这导致 send_email(...) 的修改如下:

def send_email1(subject: str, content: str):
    
    msg = EmailMessage()
    msg.set_content(content, subtype="plain", charset='us-ascii')
    msg['From'] = sender
    msg['To'] = recipient
    msg['Subject'] = subject