ホームページ  >  記事  >  バックエンド開発  >  Python Poplib モジュールと smtplib モジュールを使用して電子メールを送受信するためのチュートリアル

Python Poplib モジュールと smtplib モジュールを使用して電子メールを送受信するためのチュートリアル

WBOY
WBOYオリジナル
2016-07-22 08:56:321277ブラウズ

poplibモジュールがメールを受信します
POP3 からのメール受信には Python の Poplib モジュールが使用されます。これはメール処理の最初のステップとも言えます。
POP3 プロトコルは複雑ではありません。サーバーにコマンドを送信すると、サーバーは必ずメッセージを返します。 Pop3 コマンドコードは次のとおりです:

リーリー

Python の Poplib は、2 列目にマークされているこれらのコマンドに対応するメソッドも提供します。メールを受信するプロセスは通常次のとおりです:
1.pop3サーバー(poplib.POP3.__init__)に接続します
2. 検証のためにユーザー名とパスワードを送信します (poplib.POP3.user Poplib.POP3.pass_)
3. メールボックス(poplib.POP3.stat)内のメール情報を取得します
4. メール受信(poplib.POP3.retr)
5.メールを削除する(poplib.POP3.dele)
6. 終了 (poplib.POP3.quit)
上記の括弧内に記述したのは、この操作を完了するために使用するメソッドであることに注意してください。実際のコードではそのように記述することはできません。poplib.POP3 のオブジェクトを作成してから、このオブジェクトのメソッドを呼び出す必要があります。例:

リーリー


として理解されるべきです

リーリー

以下の実際のコードを見てください:

リーリー

一部の場所では、安全な電子メールは実際には Pop3 の SSL 暗号化であると言われています。このように、poplib でも処理できますが、POP3 クラスを使用する代わりに、POP3_SSL を使用します。メソッドは同じです。したがって、SSL をサポートするには、上記のコードで、pop3 オブジェクトを作成する行を置き換えます:

リーリー

smtplib: Python を使用して SSL/TLS 安全なメールを送信する
Python の smtplib は、電子メールを送信するための非常に便利な方法を提供します。これは単に SMTP プロトコルをカプセル化するだけです。
smtp プロトコルの基本的なコマンドは次のとおりです:

  • HELO はサーバーに対してユーザーを識別します
  • MAIL メール転送メールを初期化します:
  • RCPT は単一の電子メール受信者を識別します。多くの場合、MAIL コマンドの背後に次の目的で複数の rcpt が存在する可能性があります。
  • データ 単一または複数の RCPT コマンドの後、すべての電子メール受信者が識別され、データ送信が開始され、次で終わります。
  • VRFY は、セキュリティ上の理由により、指定されたユーザー/メールボックスが存在するかどうかを確認するために使用されます。多くの場合、サーバーはこのコマンドを禁止します。
  • EXPN は、指定されたメール リストが存在するかどうかを確認し、メール リストを展開しますが、多くの場合は無効になります
  • ヘルプ サーバーがサポートしているコマンドを問い合わせる
  • いいえ、操作はありません。サーバーは OK と応答するはずです
  • QUIT セッションを終了します
  • RSET はセッションをリセットし、現在の転送はキャンセルされます
  • MAIL FROM 送信者のアドレスを指定します
  • 指定された受信者アドレスに RCPT します
  • 一般に、SMTP セッションには 2 つの方法があります。1 つはダイレクトメール配信です。つまり、zzz@163.com にメールを送信したい場合は、163.com のメールサーバーに直接接続してレターを送信します。 zzz@163.com; もう 1 つは、確認後にメールを送信する方法です。たとえば、zzz@163.com にメールを送信するのではなく、163.com を経由します。あなたの別のメールをsina.comに送信してください。この方法では、最初にsina.comのSMTPサーバーに接続し、認証してから163.comへのレターをsina.comに送信する必要があります。sina.comは、163.comへのレターの配達を支援します。
最初のメソッドのコマンド フローは基本的に次のとおりです:

1.こんにちは

2.

からのメール 3.
への受け取り 4. データ
5. やめる
ただし、最初の送信方法には一般に制限があります。つまり、rcpt で指定された電子メール受信者はこのサーバー上に存在する必要があり、そうでない場合は受信されません。 まずはコードを見てみましょう:

リーリー

163.com にはスパム対策機能があり、上記の電子メール配信方法ではスパム対策システムの検出を通過できない可能性があることに注意してください。したがって、個人がこの方法で送信することは一般的に推奨されません。
2 番目のものは少し異なります: 1.えっ

2.認証ログイン
3.
からのメール 4.rcpt から
5.データ
6.やめる
最初のプロセスと比較すると、認証プロセスが 1 つ増えています。それは、認証ログイン プロセスです。

リーリー

    
    上面说的是最普通的情况,但是不能忽略的是现在好多企业邮件是支持安全邮件的,就是通过SSL发送的邮件,这个怎么发呢?SMTP对SSL安全邮件的支持有两种方案,一种老的是专门开启一个465端口来接收ssl邮件,另一种更新的做法是在标准的25端口的smtp上增加一个starttls的命令来支持。
    看看第一种怎么办:

#-*- encoding: gb2312 -*-
import os, sys, string, socket
import smtplib


class SMTP_SSL (smtplib.SMTP):
  def __init__(self, host='', port=465, local_hostname=None, key=None, cert=None):
    self.cert = cert
    self.key = key
    smtplib.SMTP.__init__(self, host, port, local_hostname)
    
  def connect(self, host='localhost', port=465):
    if not port and (host.find(':') == host.rfind(':')):
      i = host.rfind(':')
      if i >= 0:
        host, port = host[:i], host[i+1:]
        try: port = int(port)
        except ValueError:
          raise socket.error, "nonnumeric port"
    if not port: port = 654
    if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
    msg = "getaddrinfo returns an empty list"
    self.sock = None
    for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
      af, socktype, proto, canonname, sa = res
      try:
        self.sock = socket.socket(af, socktype, proto)
        if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
        self.sock.connect(sa)
        # 新增加的创建ssl连接
        sslobj = socket.ssl(self.sock, self.key, self.cert)
      except socket.error, msg:
        if self.debuglevel > 0: 
          print>>stderr, 'connect fail:', (host, port)
        if self.sock:
          self.sock.close()
        self.sock = None
        continue
      break
    if not self.sock:
      raise socket.error, msg

    # 设置ssl
    self.sock = smtplib.SSLFakeSocket(self.sock, sslobj)
    self.file = smtplib.SSLFakeFile(sslobj);

    (code, msg) = self.getreply()
    if self.debuglevel > 0: print>>stderr, "connect:", msg
    return (code, msg)
    
if __name__ == '__main__':
  smtp = SMTP_SSL('192.168.2.10')
  smtp.set_debuglevel(1)
  smtp.sendmail("zzz@xxx.com", "zhaowei@zhaowei.com", "xxxxxxxxxxxxxxxxx")
  smtp.quit()

    
    这里我是从原来的smtplib.SMTP派生出了新的SMTP_SSL类,它专门来处理ssl连接。我这里测试的192.168.2.10是我自己的测试服务器.
    第二种是新增加了starttls的命令,这个很简单,smtplib里就有这个方法,叫smtplib.starttls()。当然,不是所有的邮件系统都支持安全邮件的,这个需要从ehlo的返回值里来确认,如果里面有starttls,才表示支持。相对于发送普通邮件的第二种方法来说,只需要新增加一行代码就可以了:

#-*- encoding: gb2312 -*-
import os, sys, string
import smtplib
import base64

# 邮件服务器地址
mailserver = "smtp.163.com"
# 邮件用户名
username = "xxxxxx@163.com"
# 密码
password = "xxxxxxx"
# smtp会话过程中的mail from地址
from_addr = "xxxxxx@163.com"
# smtp会话过程中的rcpt to地址
to_addr = "yyyyyy@163.com"
# 信件内容
msg = "my test mail"

svr = smtplib.SMTP(mailserver)
# 设置为调试模式,就是在会话过程中会有输出信息
svr.set_debuglevel(1)
# ehlo命令,docmd方法包括了获取对方服务器返回信息,如果支持安全邮件,返回值里会有starttls提示
svr.docmd("EHLO server")
svr.starttls() # <------ 这行就是新加的支持安全邮件的代码!
# auth login 命令
svr.docmd("AUTH LOGIN")
# 发送用户名,是base64编码过的,用send发送的,所以要用getreply获取返回信息
svr.send(base64.encodestring(username))
svr.getreply()
# 发送密码
svr.send(base64.encodestring(password))
svr.getreply()
# mail from, 发送邮件发送者
svr.docmd("MAIL FROM: <%s>" % from_addr)
# rcpt to, 邮件接收者
svr.docmd("RCPT TO: <%s>" % to_addr)
# data命令,开始发送数据
svr.docmd("DATA")
# 发送正文数据
svr.send(msg)
# 比如以 . 作为正文发送结束的标记
svr.send(" . ")
svr.getreply()
# 发送结束,退出
svr.quit()

注意: 以上的代码为了方便我都没有判断返回值,严格说来,是应该判断一下返回的代码的,在smtp协议中,只有返回代码是2xx或者3xx才能继续下一步,返回4xx或5xx的,都是出错了。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。