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 プロトコルの基本的なコマンドは次のとおりです:
1.こんにちは
2.からのメール
3.
への受け取り
4. データ
5. やめる
ただし、最初の送信方法には一般に制限があります。つまり、rcpt で指定された電子メール受信者はこのサーバー上に存在する必要があり、そうでない場合は受信されません。 まずはコードを見てみましょう:
リーリー
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的,都是出错了。