我有一台運行 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”(或其他名稱)。同樣,使用電子郵件.util和電子郵件.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
。您還應該確認該連接埠沒有被防火牆阻止,並且在路由器中正確設定了任何必要的連接埠轉送。
類似地,雖然直接連接到您的郵件伺服器實際上並沒有什麼區別,但如果您要向以下地址發送郵件/接收電子郵件,您可能需要設定 MX 記錄:sigsmileyface.ddns.net。
檢查您的連接
您應該仔細檢查您的腳本是否具有正確的連接值,無論您是在物件中smptlib
還是透過.connect()
.請注意,您指定的主機名稱始終是與您希望向其發送郵件的伺服器的直接連接,或者是您希望代表您傳遞訊息的中間郵件伺服器(本地或其他)。
雖然在您的情況下似乎不太可能,但您還應該了解連接到接收伺服器所需的任何使用者名稱或密碼。當使用另一台伺服器中繼郵件時,這是最常見的,但值得記住。
檢查是否需要使用繼電器
確保您不需要使用某種繼電器。簡而言之,一些 ISP 會採取某些措施來防止垃圾郵件,這可能需要使用特殊的郵件伺服器來最初在連接埠 25 上傳輸或接收郵件。
例如,我的家庭服務的本機 ISP 會過濾連接埠 25。同時,它會阻止家庭用戶在此連接埠上傳入的訊息。
這意味著要在連接埠 25 上傳送和接收電子郵件,我必須將正常的外寄郵件(您的腳本嘗試的內容)傳遞給smtp.isp.com將其轉送至連接埠 25 上的收件人,同時使用第二個(第三方)服務將傳入郵件從連接埠 25 路由到連接埠 XXX(我的郵件伺服器實際偵聽的連接埠)。
請注意,這實際上並不會阻止在其他開放連接埠上發送或接收郵件(這對於測試或個人用途來說可能很好),但由於大多數郵件伺服器使用連接埠25 來保持一致性,從長遠來看,使用中繼可能是必要的。
如果還不夠清楚,您可以在 25 以外的連接埠上進行測試,假設您在腳本中輸入了正確的值並且可以控制接收郵件伺服器。