我有一台运行 Raspbian Jessie 的服务器,我想使用 Python 从该服务器发送电子邮件。我看到了两个可能有效的模块,包括smtpd
和smtplib
。
我见过很多例子,包括smtp.gmail.com
和localhost
。例如,我想发送一封带有特定域名的电子邮件:[email protected]
我是 SMTP 新手,收到的都是很多错误。我该如何构建 SMTP 服务器代码来实际发送电子邮件?
Traceback (most recent call last):
File "C:\Users\Josua\Desktop\smtp_test.py", line 42, in <module>
s = smtplib.SMTP('sigsmileyface.ddns.net')
File "C:\Users\Josua\AppData\Local\Programs\Python\Python36\lib\smtplib.py", line 251, in __init__
(code, msg) = self.connect(host, port)
File "C:\Users\Josua\AppData\Local\Programs\Python\Python36\lib\smtplib.py", line 336, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "C:\Users\Josua\AppData\Local\Programs\Python\Python36\lib\smtplib.py", line 307, in _get_socket
self.source_address)
File "C:\Users\Josua\AppData\Local\Programs\Python\Python36\lib\socket.py", line 724, in create_connection
raise err
File "C:\Users\Josua\AppData\Local\Programs\Python\Python36\lib\socket.py", line 713, in create_connection
sock.connect(sa)
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
答案1
免责声明
我预计以下至少部分信息对您来说是多余的。请耐心等待。=)
smtplib 与 smptd
Python 有两个处理电子邮件的模块——smtplib和邮件传输协议。两者的区别在于smtplib
用于发送电子邮件,而smptd
用于接收电子邮件。在这种情况下,对于发送电子邮件,您只需要使用smtplib
。
使用 Python 3.6 smtplib 发送电子邮件
我想通过我的域名发送电子邮件(例如[电子邮件保护])。
由于您没有提供源脚本,我在下面列出了一个可用的 Python 3.6 邮件脚本供参考:
# Python mail script with smtplib, email.utils and email.mime.text.
# --- imports ---
import smtplib
import email.utils
from email.mime.text import MIMEText
# --- create our message ---
# Create our message.
msg = MIMEText('The body of your message.')
msg['To'] = email.utils.formataddr(('Recipient Name', '[email protected]'))
msg['From'] = email.utils.formataddr(('Your Name', '[email protected]'))
msg['Subject'] = 'Your Subject'
# --- send the email ---
# SMTP() is used with normal, unencrypted (non-SSL) email.
# To send email via an SSL connection, use SMTP_SSL().
server = smtplib.SMTP()
# Specifying an empty server.connect() statement defaults to ('localhost', 25).
# Therefore, we specify which mail server we wish to connect to.
server.connect ('mail.example.com', 25)
# Optional login for the receiving mail_server.
# server.login ('[email protected]', 'Password')
# Dump communication with the receiving server straight to to the console.
# server.set_debuglevel(True)
# '[email protected]' is our envelope address and specifies the return
# path for bounced emails.
try:
server.sendmail('[email protected]', ['[email protected]'], msg.as_string())
finally:
server.quit()
请注意,虽然我使用“server”作为smtplib
对象名称,但您可以自由地在自己的脚本中继续使用“s”(或其他名称)。同样,使用电子邮件实用程序和电子邮件.mime模块不是绝对必要的,但它们有助于构建最终的消息。
我是 SMTP 新手,我遇到的都是很多错误。
我不能说你的其他错误可能是由什么引起的,但你列出的输出表明与sigsmileyface.ddns.net无法在端口 25 上建立。关键行是:
s = smtplib.SMTP('sigsmileyface.ddns.net')
,默认为端口 25。最后一行
ConnectionRefusedError: [...] the target machine actively refused it
可能表明防火墙或邮件服务器配置存在问题。
故障排除
检查邮件服务器和端口
确定您所连接的服务器是否有活动的邮件服务器以及它在哪个端口上运行(通常使用端口 25 来接收邮件)。
就你的情况而言,如果你能控制sigsmileyface.ddns.net并尝试向其发送电子邮件,您应该检查您的邮件服务器是否正确设置以在端口 25 上接收邮件。我相信这sendmail
是 Pi 上的标准邮件服务器。您还应该确认该端口未被防火墙阻止,并且路由器中正确设置了任何必要的端口转发。
同样,虽然直接连接到邮件服务器应该没什么区别,但如果您要向/接收电子邮件,您可能需要设置 MX 记录sigsmileyface.ddns.net。
检查您的连接
您应该仔细检查脚本是否具有正确的连接值,无论您是在对象中smptlib
还是通过指定它们.connect()
。请注意,您指定的主机名将始终是与您希望发送邮件的服务器的直接连接,或者是您希望代表您传递消息的中介邮件服务器(本地或其他)。
虽然这种情况不太可能发生,但您也应该知道连接到接收服务器所需的用户名或密码。这在使用另一台服务器中继邮件时最常见,但值得记住。
检查是否需要使用中继
确保您不需要使用某种中继。简而言之,一些 ISP 会采取某些措施来防止垃圾邮件,这可能需要使用特殊的邮件服务器在端口 25 上最初传输或接收消息。
例如,我家服务的本地 ISP 过滤了端口 25。它强制发往此端口的正常外发邮件通过 ISP SSL 邮件中继发送。同时,它阻止家庭用户通过此端口接收邮件。
这意味着要在端口 25 上发送和接收电子邮件,我必须将正常的外发邮件(您的脚本正在尝试的)传递给smtp.isp.com将其转发给端口 25 上的收件人,同时使用第二个(第三方)服务将传入的邮件从端口 25 路由到端口 XXX(我的邮件服务器实际监听的位置)。
请注意,这实际上并不阻止在其他开放端口上发送或接收邮件(这对于测试或个人用途来说没问题),但由于大多数邮件服务器使用端口 25 来保持一致性,因此从长远来看,使用中继可能是必要的。
如果还不够清楚的话,您可以在 25 以外的端口上进行测试,假设您在脚本中输入了正确的值并且可以控制接收邮件服务器。