Pythonはさまざまな姿勢でメールを送信します

この章の内容

  • Python標準ライブラリsmtplib

  • PythonはメールとCCを送信します

  • Pythonは添付ファイル付きのメールを送信します

  • PythonはHTMLメールを送信します

  • Pythonは画像メールを送信します

スクリプトを作成するときは、バックグラウンドで実行します。実行状況を知りたい場合は、メール、SMS(テキストメッセージ)、Fetion、WeChatなどで管理者に通知します。最もよく使われるのはメールです。Linuxでは、メールアラートを送信するシェルスクリプトは非常に簡単です。
スクリプトを作成するときにバックグラウンドで実行される既製のメールサーバーがあります。実行ステータスを知りたい場合は、メール、SMS(ショートメッセージ)、 Fetion、WeChatなど。管理者に通知してください。最もよく使用されるのはメールです。Linuxでは、シェルスクリプトを使用して電子メールアラートを送信するのは非常に簡単です。既製の電子メールサービスソフトウェアがあるか、オペレーターのメールボックスサーバーを呼び出します。
Pythonの場合、メールを送信するためにメールサーバーを呼び出すスクリプトを作成する必要があり、使用されるプロトコルはSMTPです。メールを受信するために使用されるプロトコルは、POP3とIMAPです。POP3とIMAPの違いを説明する必要があると思います。クライアントメールボックスでPOP3によって実行される操作は、電子メールの削除など、メールボックスサーバーにフィードバックされず、メールボックスサーバーは削除されません。IMAPはメールボックスサーバーにフィードバックし、対応する操作を実行します。

1.Python標準ライブラリsmtplib

Pythonは、電子メールを送受信するためのライブラリ(smtplib、poplib、およびimaplib)を提供します。
smtplibライブラリは電子メールの送信に使用され、smtplibライブラリは主にSMTPサーバーへの接続と電子メールの送信に使用されるsmtplib.SMTP()クラスを使用します。
このクラスには、一般的に使用されるメソッドがいくつかあります。

Pythonはさまざまな姿勢でメールを送信します
公式の例を見てください:

>>> import smtplib
>>> s=smtplib.SMTP("localhost")
>>> tolist=["[email protected]","[email protected]","[email protected]","[email protected]"]
>>> msg = '''\
     ... From: [email protected]
     ... Subject: testin'...
     ...
     ... This is a test '''
>>> s.sendmail("[email protected]",tolist,msg)
     { "[email protected]" : ( 550 ,"User unknown" ) }
>>> s.quit()

例に基づいてメールテストを送信しましょう。
ローカルSMTPサーバーを使用してテストします。つまり、sendmail、postfixなどのSMTPプロトコルをサポートするサービスをインストールします。
CentOS install sendmail:yum install sendmail

>>> import smtplib
>>> s = smtplib.SMTP("localhost")
>>> tolist = ["[email protected]", "[email protected]"]
>>> msg = '''\
... From: [email protected]
... Subject: test
... This is a test '''
>>> s.sendmail("[email protected]", tolist, msg)
{}

TencentとNetEaseの受信者のメールボックスを入力すると、送信されたばかりのテストメールが表示されます。これらは通常、メールボックスサーバーによってスパムとしてフィルタリングされるため、受信トレイはありません。ゴミ箱に移動する必要があります。

Pythonはさまざまな姿勢でメールを送信します

ご覧のとおり、グループ送信用に複数の受信者をリストに入れることができます。msgオブジェクトでは、Fromは送信者を表し、Subjectは電子メールのタイトルであり、電子メールの内容は改行の後に入力されます。
上記は、ローカルSMTPサーバーを使用して送信されたメールです。テストでは、163サーバーを使用してメールを送信し、効果を確認します。

>>> import smtplib
>>> s = smtplib.SMTP("smtp.163.com")
>>> s.login("[email protected]", "xxx")
(235, 'Authentication successful')
>>> tolist = ["[email protected]", "[email protected]"]
>>> msg = '''\
... From: [email protected]
... Subject: test
... This is a test '''
>>> s.sendmail("[email protected]", tolist, msg)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.6/smtplib.py", line 725, in sendmail
    raise SMTPDataError(code, resp)
smtplib.SMTPDataError: (554, 'DT:SPM 163 smtp10,DsCowAAXIdDIJAtYkZiTAA--.65425S2 1477125592,please see http://mail.163.com/help/help_spam_16.htm?ip=119.57.73.67&hostid=smtp10&time=1477125592')

指定された163URLにアクセスすると、SMTP554エラーは次のようになります。「554DT:SUM封筒の送信者とレターヘッドの送信者が一致しません。」
その意味はすでに理解しています。上記のローカルSMTPサーバーを使用すると、受信者の場所は「 undisclosed "-recipients"、163 SMTPサーバーがサービスを提供しない理由は、受信者がここで指定されていないためです。
msgオブジェクトを再変更し、受信者を追加します。

>>> msg = '''\           
... From: [email protected]
... To: [email protected] ,[email protected]
... Subject: test
...
... This is a test '''
>>> s.sendmail("[email protected]", tolist, msg)
{}

Pythonはさまざまな姿勢でメールを送信します

さて、あなたは普通にメールを送ることができます。msgの形式はSMTPによって規制されており、従う必要があります。

2.PythonはメールとCCを送信します

#!/usr/bin/python
# -*- coding: utf-8 -*-
import smtplib
def sendMail(body):
    smtp_server = 'smtp.163.com'
    from_mail = '[email protected]'
    mail_pass = 'xxx'
    to_mail = ['[email protected]', '[email protected]']
    cc_mail = ['[email protected]']
    from_name = 'monitor' 
    subject = u'监控'.encode('gbk')   # 以gbk编码发送,一般邮件客户端都能识别
#     msg = '''\
# From: %s <%s>
# To: %s
# Subject: %s
# %s''' %(from_name, from_mail, to_mail_str, subject, body)  # 这种方式必须将邮件头信息靠左,也就是每行开头不能用空格,否则报SMTP 554
    mail = [
        "From: %s <%s>" % (from_name, from_mail),
        "To: %s" % ','.join(to_mail),   # 转成字符串,以逗号分隔元素
        "Subject: %s" % subject,
        "Cc: %s" % ','.join(cc_mail),
        "",
        body
        ]
    msg = '\n'.join(mail)  # 这种方式先将头信息放到列表中,然后用join拼接,并以换行符分隔元素,结果就是和上面注释一样了
    try:
        s = smtplib.SMTP()
        s.connect(smtp_server, '25')
        s.login(from_mail, mail_pass)
        s.sendmail(from_mail, to_mail+cc_mail, msg)   
        s.quit()
    except smtplib.SMTPException as e:
        print "Error: %s" %e
if __name__ == "__main__":
sendMail("This is a test!")

Pythonはさまざまな姿勢でメールを送信します

s.sendmail(from_mail、to_mail + cc_mail、msg)ここで、受信者とCC送信者を一緒に送信する必要があるのはなぜですか?実際、受信者であろうとCCであろうと、受信する電子メールは同じであり、SMTPは受信者がそれらを1つずつ送信すると想定します。したがって、実際にはCCの概念はなく、電子メールのヘッダーに個人の情報を追加するだけです。また、本人をコピーする必要がない場合は、上記のccの情報を削除してください。

3.Pythonは添付ファイル付きのメールを送信します

SMTP.sendmail()メソッドは添付ファイルの追加をサポートしていないため、電子メールモジュールを使用してニーズを満たすことができます。電子メールモジュールは、電子メールを作成および解析するためのモジュールです。
まず、電子メールライブラリを使用して簡単な電子メールを作成する方法を見てみましょう。

message = Message()
message['Subject'] = '邮件主题'
message['From'] = from_mail
message['To'] = to_mail
message['Cc'] = cc_mail
message.set_payload('邮件内容')

基本フォーマットはこんな感じ!
トピックに戻り、添付ファイル付きの電子メールを送信します。

#!/usr/bin/python
# -*- coding: utf-8 -*-
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email import encoders
from email.mime.base import MIMEBase
from email.utils import parseaddr, formataddr
# 格式化邮件地址
def formatAddr(s):
    name, addr = parseaddr(s)
    return formataddr((Header(name, 'utf-8').encode(), addr))
def sendMail(body, attachment):
    smtp_server = 'smtp.163.com'
    from_mail = '[email protected]'
    mail_pass = 'xxx'
    to_mail = ['[email protected]', '[email protected]']
    # 构造一个MIMEMultipart对象代表邮件本身
    msg = MIMEMultipart()
    # Header对中文进行转码
    msg['From'] = formatAddr('管理员 <%s>' % from_mail).encode()
    msg['To'] = ','.join(to_mail)
    msg['Subject'] = Header('监控', 'utf-8').encode()
    # plain代表纯文本
    msg.attach(MIMEText(body, 'plain', 'utf-8'))
    # 二进制方式模式文件
    with open(attachment, 'rb') as f:
        # MIMEBase表示附件的对象
        mime = MIMEBase('text', 'txt', filename=attachment)
        # filename是显示附件名字
        mime.add_header('Content-Disposition', 'attachment', filename=attachment)
        # 获取附件内容
        mime.set_payload(f.read())
        encoders.encode_base64(mime)
        # 作为附件添加到邮件
        msg.attach(mime)
    try:
        s = smtplib.SMTP()
        s.connect(smtp_server, "25")
        s.login(from_mail, mail_pass)
        s.sendmail(from_mail, to_mail, msg.as_string())  # as_string()把MIMEText对象变成str
        s.quit()
    except smtplib.SMTPException as e:
        print "Error: %s" % e
if __name__ == "__main__":
    sendMail('附件是测试数据, 请查收!', 'test.txt')

Pythonはさまざまな姿勢でメールを送信します

4.PythonはHTMLメールを送信します

#!/usr/bin/python
# -*- coding: utf-8 -*-
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.utils import parseaddr, formataddr
# 格式化邮件地址
def formatAddr(s):
    name, addr = parseaddr(s)
    return formataddr((Header(name, 'utf-8').encode(), addr))
def sendMail(body):
    smtp_server = 'smtp.163.com'
    from_mail = '[email protected]'
    mail_pass = 'xxx'
    to_mail = ['[email protected]', '[email protected]']
    # 构造一个MIMEMultipart对象代表邮件本身
    msg = MIMEMultipart() 
    # Header对中文进行转码
    msg['From'] = formatAddr('管理员 <%s>' % from_mail).encode()
    msg['To'] = ','.join(to_mail)
    msg['Subject'] = Header('监控', 'utf-8').encode()
    msg.attach(MIMEText(body, 'html', 'utf-8'))
    try:
        s = smtplib.SMTP()     
        s.connect(smtp_server, "25")   
        s.login(from_mail, mail_pass)
        s.sendmail(from_mail, to_mail, msg.as_string())  # as_string()把MIMEText对象变成str     
        s.quit()
    except smtplib.SMTPException as e:
        print "Error: %s" % e
if __name__ == "__main__":
    body = """
    <h1>测试邮件</h1>
    <h2 style="color:red">This is a test</h1>
    """
    sendMail(body)

Pythonはさまざまな姿勢でメールを送信します

5.Pythonは画像メールを送信します

#!/usr/bin/python
# -*- coding: utf-8 -*-
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.utils import parseaddr, formataddr
# 格式化邮件地址
def formatAddr(s):
    name, addr = parseaddr(s)
    return formataddr((Header(name, 'utf-8').encode(), addr))
def sendMail(body, image):
    smtp_server = 'smtp.163.com'
    from_mail = '[email protected]'
    mail_pass = 'xxx'
    to_mail = ['[email protected]', '[email protected]']
    # 构造一个MIMEMultipart对象代表邮件本身
    msg = MIMEMultipart() 
    # Header对中文进行转码
    msg['From'] = formatAddr('管理员 <%s>' % from_mail).encode()
    msg['To'] = ','.join(to_mail)
    msg['Subject'] = Header('监控', 'utf-8').encode()
    msg.attach(MIMEText(body, 'html', 'utf-8'))
    # 二进制模式读取图片
    with open(image, 'rb') as f:
        msgImage = MIMEImage(f.read())
    # 定义图片ID
    msgImage.add_header('Content-ID', '<image1>')
    msg.attach(msgImage)
    try:
        s = smtplib.SMTP()     
        s.connect(smtp_server, "25")   
        s.login(from_mail, mail_pass)
        s.sendmail(from_mail, to_mail, msg.as_string())  # as_string()把MIMEText对象变成str     
        s.quit()
    except smtplib.SMTPException as e:
        print "Error: %s" % e
if __name__ == "__main__":
    body = """
    <h1>测试图片</h1>
    <img src="cid:image1"/>    # 引用图片
    """
    sendMail(body, 'test.png')

Pythonはさまざまな姿勢でメールを送信します

上記はPythonでメールを送信する一般的な方法ですが、スクリプトを頻繁に作成する友人は、それでも慣れている必要があります。

おすすめ

転載: blog.51cto.com/15127501/2657165