使用 smtplib 发送电子邮件,没有错误,但没有传递消息

Sending email with smtplib, no errors but no messages delivered

**UPDATE2:在 V2 的最后一段代码中,我将 smtp.sendmail(email_address, address, msg,) 替换为 smtp.sendmail(email_address, phone_book, msg,) 直接访问 phone_book 似乎已经解决了这个问题。这是任何正在寻找的人的工作代码:

import smtplib

email_address = '' # Your email goes here
email_password = '' # Your password goes here
phone_book = [''] # List of receivers


def Add_Email():
    client_email = input('Email of receiver? ')
    phone_book.append(client_email)

def Add_Subject_Message_Send():    
    with smtplib.SMTP('smtp.gmail.com', 587) as smtp:
            smtp.ehlo()
            smtp.starttls()
            smtp.ehlo()

            smtp.login(email_address, email_password)

            subject = input('Enter your subject here: ')
            body = input('Enter your message here: ')

            msg = f'Subject: {subject}\n\n{body}'

            for i in phone_book:
                address = i
                smtp.sendmail(email_address, phone_book, msg,)


Add_Email()
Add_Subject_Message_Send()

**

**更新:我用没有 GUI 的最简单版本交换了代码。当主题和正文在代码中定义时,V1 起作用。当用户定义主题和正文时,V2 不起作用。现在 V2 有这个错误信息:

Traceback (most recent call last):
  File "c:/Users/Me/Desktop/work/infosend/test4.py", line 33, in <module>
    Add_Subject_Message_Send()
  File "c:/Users/Me/Desktop/work/infosend/test4.py", line 29, in Add_Subject_Message_Send
    smtp.sendmail(email_address, address, msg,)
  File "C:\python\lib\smtplib.py", line 885, in sendmail
    raise SMTPRecipientsRefused(senderrs)
smtplib.SMTPRecipientsRefused: {'': (555, b'5.5.2 Syntax error. l15sm65056407wrv.39 - gsmtp')}

**

我正在使用 smtplib 发送电子邮件。只要在代码中定义了消息的主题和正文,一切都会正常进行,并且电子邮件会被发送。当代码中没有定义主题或正文时,不会显示错误,但不会传递消息。

我想创建一个函数,允许我编写主题和消息是什么,而不是在代码中定义它们。我的功能似乎可以正常工作,但没有传递任何消息,也没有收到任何错误消息。

附上我的代码的两个版本。

第一个版本有效。它定义了主题和正文。

第二个版本不起作用。包括定义主题和正文的功能。终端中没有收到错误。

V1

import smtplib

email_address = '' # Enter your email address here
email_password = '' # Enter your email password here

phone_book = [''] # Here enter the email of receiver

with smtplib.SMTP('smtp.gmail.com', 587) as smtp: # Connects with GMAIL
            smtp.ehlo()
            smtp.starttls()
            smtp.ehlo()

            smtp.login(email_address, email_password)

            subject = 'test3' # Subject and body defined in code = works
            body = 'test3'

            msg = f'Subject: {subject}\n\n{body}'

            for i in phone_book:
                address = i
                smtp.sendmail(email_address, address, msg,)

V2

    import smtplib

email_address = '' # Your email goes here
email_password = '' # Your password goes here
phone_book = [''] # List of receivers


def Add_Email():
    client_email = input('Email of receiver? ')
    phone_book.append(client_email)

def Add_Subject_Message_Send():    
    with smtplib.SMTP('smtp.gmail.com', 587) as smtp:
            smtp.ehlo()
            smtp.starttls()
            smtp.ehlo()

            smtp.login(email_address, email_password)

            subject = input('Enter your subject here: ')
            body = input('Enter your message here: ')

            msg = f'Subject: {subject}\n\n{body}'

            for i in phone_book:
                address = i
                smtp.sendmail(email_address, address, msg,)


Add_Email()
Add_Subject_Message_Send()

而不是: 地址 = phone_book

尝试使用: 地址=我

我认为问题可能在于您将地址变量设置为列表而不是列表中的单个项目。

我无法重现您声称从代码的早期版本中得到的语法错误。但是,您的尝试还有一些其他问题。

首先,要排除故障,请尝试添加

smtp.set_debuglevel(1)

准确显示您发送的内容。理解生成的抄本需要了解 SMTP,但如果您以后有类似的问题,包括这份抄本可能很有价值。

其次,像这样在循环中重复发送相同的邮件是有问题的——这是浪费,并且可能触发自动反垃圾邮件控制。要向多个收件人发送相同的消息,只需在对 sendmail 的调用中列出所有收件人(基本上将它们作为 Bcc: 收件人)。

第三,您的电子邮件信息模型真的太简单了。如果这两个部分都是普通的 ASCII 字符串,则只有 Subject: 和简单文本正文的最小消息是有效的,但现代电子邮件消息需要编码,否则就需要编码(例如 Unicode 字符串或二进制附件)。当然,您可以自己拼凑出一条有效的消息,但这很乏味;您应该改用 Python email 库。

这里是 the documentation.

的简短改编
import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg['From'] = email_address
msg['To'] = ', '.join(phone_book)
msg['Subject'] = subject
msg.set_content(body)

with smtplib.SMTP('smtp.gmail.com', 587) as smtp:
    smtp.ehlo()
    smtp.starttls()
    smtp.ehlo()

    smtp.login(email_address, email_password)

    smtp.send_message(msg)
    smtp.quit()

有许多使用遗留 email.message.Message class 的旧示例,但现在应避免使用这些示例。 email 库在 Python 3.3 中引入,并在 3.5 中成为官方推荐版本。

请参考我的代码。我已经这样做了,而且很有效。 你可以通过参考我的代码获得一些线索。

检查main功能代码。

import smtplib

from string import Template

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

MY_ADDRESS = 'xyz@gmail.com'
PASSWORD = 'YourPassword'


def get_contacts(filename):
    names = []
    emails = []
    with open(filename, mode='r', encoding='utf-8') as contacts_file:
        for a_contact in contacts_file:
            names.append(a_contact.split()[0])
            emails.append(a_contact.split()[1])
    return names, emails


def read_template(filename):
    with open(filename, 'r', encoding='utf-8') as template_file:
        template_file_content = template_file.read()
    return Template(template_file_content)


def main():
    names, emails = get_contacts('C:/Users/VAIBHAV/Desktop/mycontacts.txt')  # read contacts
    message_template = read_template('C:/Users/VAIBHAV/Desktop/message.txt')
    s = smtplib.SMTP(host='smtp.gmail.com', port=587)
    s.starttls()
    s.login(MY_ADDRESS, PASSWORD)
    for name, email in zip(names, emails):
        msg = MIMEMultipart()  # create a message
        message = message_template.substitute(PERSON_NAME=name.title())
        print(message)
        msg['From'] = MY_ADDRESS
        msg['To'] = email
        msg['Subject'] = "Sending mail to all"
        msg.attach(MIMEText(message, 'plain'))
        s.send_message(msg)
        del msg
    s.quit()
if __name__ == '__main__':
    main()