python email ==> send 发送邮件 :) [smtplib, email 模块]

关于Email的预备知识:

原贴地址:http://www.cnblogs.com/lonelycatcher/archive/2012/02/09/2343480.html

#########################################################################

可以使用Python的email模块来实现带有附件的邮件的发送。

SMTP (Simple Mail Transfer Protocol)
  邮件传送代理 (Mail Transfer Agent,MTA) 程序使用SMTP协议来发送电邮到接收者的邮件服务器。SMTP协议只能用来发送邮件,不能用来接收邮件。大多数的邮件发送服务器 (Outgoing Mail Server) 都是使用SMTP协议。SMTP协议的默认TCP端口号是25。

  SMTP协议的一个重要特点是它能够接力传送邮件。它工作在两种情况下:一是电子邮件从客户机传输到服务器;二是从某一个服务器传输到另一个服务器。

POP3 (Post Office Protocol) & IMAP (Internet Message Access Protocol)
  POP协议和IMAP协议是用于邮件接收的最常见的两种协议。几乎所有的邮件客户端和服务器都支持这两种协议。

  POP3协议为用户提供了一种简单、标准的方式来访问邮箱和获取电邮。使用POP3协议的电邮客户端通常的工作过程是:连接服务器、获取所有信息并保存在用户主机、从服务器删除这些消息然后断开连接。POP3协议的默认TCP端口号是110。

  IMAP协议也提供了方便的邮件下载服务,让用户能进行离线阅读。使用IMAP协议的电邮客户端通常把信息保留在服务器上直到用户显式删除。这种特性使得多个客户端可以同时管理一个邮箱。IMAP协议提供了摘要浏览功能,可以让用户在阅读完所有的邮件到达时间、主题、发件人、大小等信息后再决定是否下载。IMAP协议的默认TCP端口号是143。

邮件格式 (RFC 2822)
  每封邮件都有两个部分:邮件头和邮件体,两者使用一个空行分隔。

  邮件头每个字段 (Field) 包括两部分:字段名和字段值,两者使用冒号分隔。有两个字段需要注意:From和Sender字段。From字段指明的是邮件的作者,Sender字段指明的是邮件的发送者。如果From字段包含多于一个的作者,必须指定Sender字段;如果From字段只有一个作者并且作者和发送者相同,那么不应该再使用Sender字段,否则From字段和Sender字段应该同时使用。

  邮件体包含邮件的内容,它的类型由邮件头的Content-Type字段指明。RFC 2822定义的邮件格式中,邮件体只是单纯的ASCII编码的字符序列。

MIME (Multipurpose Internet Mail Extensions) (RFC 1341)
  MIME扩展邮件的格式,用以支持非ASCII编码的文本、非文本附件以及包含多个部分 (multi-part) 的邮件体等。

Python email模块

1. class email.message.Message

__getitem__,__setitem__实现obj[key]形式的访问。
Msg.attach(playload): 向当前Msg添加playload。
Msg.set_playload(playload): 把整个Msg对象的邮件体设成playload。
Msg.add_header(_name, _value, **_params): 添加邮件头字段。
2. class email.mime.base.MIMEBase(_maintype, _subtype, **_params)
  所有MIME类的基类,是email.message.Message类的子类。

3. class email.mime.multipart.MIMEMultipart()
  在3.0版本的email模块 (Python 2.3-Python 2.5) 中,这个类位于email.MIMEMultipart.MIMEMultipart。
  这个类是MIMEBase的直接子类,用来生成包含多个部分的邮件体的MIME对象。

4. class email.mime.text.MIMEText(_text)
  使用字符串_text来生成MIME对象的主体文本。
####################################################################

#     上面的关于email 和 python的内容非常详细。 不过作者原帖的实例代码就有点罗嗦了。不若下面的实例简易。当然,如果追求email发送格式的多样性,还是采用上文作者的做法,做这样的操作 

from email.mime.multipart import MIMEMultipart

from email.mime.base import MIMEBase

from email.mime.text import MIMEText

from email.utils import COMMASPACE,formatdate
from email import encoders
 
import os

#  不过个人觉得这些很罗嗦呀, 不过原作者的代码还是值得一看的。http://www.cnblogs.com/lonelycatcher/archive/2012/02/09/2343480.html

**********************************************

好了,现在我们来看看常用的python email 发送方法吧

write a send_mail.py

我采用的是这个的案例来的。非常简单原帖地址: http://www.linuxidc.com/Linux/2011-11/47542.htm

下面是代码,

touch send_mail.py && vim send_mail.py

下面上mail的源码

#!/usr/bin/env python   
# -*- coding: utf-8 -*-   
#导入smtplib和MIMEText   
import smtplib  
from email.mime.text import MIMEText  
#############   
#要发给谁,这里发给2个人   
mailto_list=["3xxxxxxxx@qq.com","ixxxxxxxx@gmail.com"]  
#####################   
#设置服务器,用户名、口令以及邮箱的后缀   
mail_host="smtp.sina.com"           ##请注意,这里需要你的邮箱服务提供商已经为你开启了smtp服务
mail_user="axxxxxxx"  #你的email用户名
mail_pass="fxxxxxxxx"  
mail_postfix="sina.com"  
######################   
def send_mail(to_list,sub,content):  
#''''' 
#to_list:发给谁 
#sub:主题 
#content:内容 
#send_mail("aaa@126.com","sub","content") 
#'''''  
    me=mail_user+"<"+mail_user+"@"+mail_postfix+">"  
    msg = MIMEText(content)  
    msg['Subject'] = sub #设置主题   
    msg['From'] = me     #发件人   
    msg['To'] = ";".join(to_list) #收件人   
    try:  
        s = smtplib.SMTP()  
        s.connect(mail_host)  
        s.login(mail_user,mail_pass)  
        s.sendmail(me, to_list, msg.as_string())  
        s.close()  
        return True  
    except Exception, e:  
        print str(e)  
        return False  
if __name__ == '__main__':  
    if send_mail(mailto_list,"Hey subject","This is content"):  
        print "发送成功"  
    else:  
        print "发送失败"  

然后我们尝试

alex@universe ~/sandbox/env_27_flask/mail_proj $ python send_mail.py 
发送成功

# python 使用的是2.7.4版本的。

很容易,我们可以看到收到邮件截屏。

至于那个gmail的也会收到。但是上面我们发现收到的内容是群发的,所以我们可以看到不同的人收信件都可以看到所有的收取人的。

这里我们需要几个功能

1. 抄送( CC ) 或者 秘送( BC ) 功能

2. 信件方式,为HTML 页面类型。 上面我们发送的邮件格式是text

        是由于 from email.mime.text import MIMEText   这个的原因, 这里我们需要发送html格式的邮件。

        不信我们可以再写一封邮件发送,看到

如果修改成这样的话,文字里面加了一个 这个符号,代表换行 text 文件类型

我们将看到这样的

×××××××××××××××××××××××

上面的HTML代码并没有解析,因为只是当了text发送了,所以页面是不会解析的。所以需要修改一下才好。这样就可以直接发送网页页面啦!

这里我找到这样的资料:Sending HTML email in Python 地址为:http://stackoverflow.com/questions/882712/sending-html-email-in-python

Here’s an example of how to create an HTML message with an alternative plain text version:

#! /usr/bin/python

import smtplib

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

# me == my email address
# you == recipient's email address
me = "my@email.com"
you = "your@email.com"

# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = "Link"
msg['From'] = me
msg['To'] = you

# Create the body of the message (a plain-text and an HTML version).
text = "Hi!
How are you?
Here is the link you wanted:
http://www.python.org"
html = """
<html>
  <head></head>
  <body>
    <p>Hi!<br>
       How are you?<br>
       Here is the <a href="http://www.python.org">link</a> you wanted.
    </p>
  </body>
</html>
"""

# Record the MIME types of both parts - text/plain and text/html.
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')

# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(part1)
msg.attach(part2)

# Send the message via local SMTP server.
s = smtplib.SMTP('localhost')
# sendmail function takes 3 arguments: sender's address, recipient's address
# and message to send - here it is sent as one string.
s.sendmail(me, you, msg.as_string())
s.quit()

上面的用法真的挺独特的。很独特。

强烈推荐这种方式发邮件!!!

这里被我修改成下面的样子

#!/usr/bin/env python

import smtplib

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

# me == my email address
# you == recipient's email address
me = "xxxxxxxxx@sina.com"
you = "xxxxxxxxx@qq.com"

# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = "Link"
msg['From'] = me
msg['To'] = you

# Create the body of the message (a plain-text and an HTML version).
text = "Hi!
How are you?
Here is the link you wanted:
http://www.python.org"
html = """
        <html>
  <head></head>
  <body>
    <p>Hi!<br>
       How are you?<br>
       Here is the <a href="http://www.python.org">link</a> you wanted.
    </p>
  </body>
</html>
"""

# Record the MIME types of both parts - text/plain and text/html.
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')

# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(part1)
msg.attach(part2) ## 如果里面有了html内容,那么html类型的文档就被更受青睐,在下面的演示中,text的文档内容是看不到的。(优先级小,直接被省略了)
try:
    # Send the message via local SMTP server.
    s = smtplib.SMTP('smtp.sina.com') # in this case 'smtp.sina.com'
    s.login('myusername','mypassword')         ##上面链接粗心的好心人忘记建立登录链接了
    # sendmail function takes 3 arguments: sender's address, recipient's address
    # and message to send - here it is sent as one string.
    s.sendmail(me, you, msg.as_string())
    s.quit()
    print 'mail sent'
except Exception, e:              ## 请记住这个try: except Exception, e:  的好习惯,能帮助你运行不了的时候debug,不要粗心学那个家伙
    print 'mail not sent'
    print str(e) 

结果如下:

 

现在我们看到邮箱里面的内容已经变成了html页面样子了。详情请看上面写的代码。

激动人心的时刻来临啦!!

下面是我写的新得代码。很有意思的

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import smtplib
# this module is used for interesting things like a fortune a day
# import subprocess
import os

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

def send_a_mail(frm, to, server,password, subject, content):
    # me == my email address
    # you == recipient's email address
    me = frm
    you = to
    
    # Create message container - the correct MIME type is multipart/alternative.
    msg = MIMEMultipart('alternative')
    msg['Subject'] = subject
    msg['From'] = me
    msg['To'] = you
    
    # Create the body of the message (a plain-text and an HTML version).
#    text = "Hi!
How are you?
Here is the link you wanted:
http://www.python.org"
    
    # Record the MIME types of both parts - text/plain and text/html.
#    part1 = MIMEText(text, 'plain')
    part2 = MIMEText(content, 'html')
    
    # Attach parts into message container.
    # According to RFC 2046, the last part of a multipart message, in this case
    # the HTML message, is best and preferred.
#    msg.attach(part1)
    msg.attach(part2) ## 如果里面有了html内容,那么html类型的文档就被更受青睐,在下面的演示中,text的文档内容是看不到的。(优先级小,直接被省略了)
    try:
        # Send the message via local SMTP server.
        s = smtplib.SMTP(server) # in this case 'smtp.sina.com'
        s.login(me.split('@')[0], password)         ##上面链接粗心的好心人忘记建立登录链接了
        # sendmail function takes 3 arguments: sender's address, recipient's address
        # and message to send - here it is sent as one string.
        s.sendmail(me, you, msg.as_string())
        s.quit()
        return True
    except Exception, e:              ## 请记住这个try: except Exception, e:  的好习惯,能帮助你运行不了的时候debug,不要粗心学那个家伙
        print str(e) 
        return False

if __name__=="__main__":
    fortune = os.popen('fortune')
    twitter = fortune.read()
    html = """
                    <html>
      <head></head>
      <body>
        <p>Hi!<br>
           How are you?<br>
           Here is the <a href="http://www.python.org">link</a> you wanted.
        </p>
        <b>有没有看到,这是一封经过全自动化python脚本发送的电子邮件</b>
        <br>
        <p>
        <h2>每次随机一句</h2>
        <font color="magenta">
        <b>
    """     
    html = html + twitter + """
      </b>
      </font>
      </body>
    </html>
    """
    if send_a_mail('xxxxxxxxxxxx@126.com','xxxxxxxxxxxxxxx@qq.com','smtp.126.com','yourpassword','全自动发电子邮件脚本', html):
        print "mail sent"
    else:
        print "mail not sent"

关于怎么在python中使用linux命令这里是链接:http://www.cyberciti.biz/faq/python-execute-unix-linux-command-examples/ 非常详细的介绍

快来看看演示页面吧

具体代码为下:

很爽很酷的代码,

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# written by Spaceship9
# Please note the author if this is used by any others
import smtplib
# this module is used for interesting things like a fortune a day
# import subprocess
import os

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

def send_a_mail(frm, to, server,password, subject, content):
    # me == my email address
    # you == recipient's email address
    me = frm
    you = to
    
    # Create message container - the correct MIME type is multipart/alternative.
    msg = MIMEMultipart('alternative')
    msg['Subject'] = subject
    msg['From'] = me
    msg['To'] = you
    
    # Create the body of the message (a plain-text and an HTML version).
#    text = "Hi!
How are you?
Here is the link you wanted:
http://www.python.org"
    
    # Record the MIME types of both parts - text/plain and text/html.
#    part1 = MIMEText(text, 'plain')
    part2 = MIMEText(content, 'html')
    
    # Attach parts into message container.
    # According to RFC 2046, the last part of a multipart message, in this case
    # the HTML message, is best and preferred.
#    msg.attach(part1)
    msg.attach(part2) ## 如果里面有了html内容,那么html类型的文档就被更受青睐,在下面的演示中,text的文档内容是看不到的。(优先级小,直接被省略了)
    try:
        # Send the message via local SMTP server.
        s = smtplib.SMTP(server) # in this case 'smtp.sina.com'
        s.login(me.split('@')[0], password)         ##上面链接粗心的好心人忘记建立登录链接了
        # sendmail function takes 3 arguments: sender's address, recipient's address
        # and message to send - here it is sent as one string.
        s.sendmail(me, you, msg.as_string())
        s.quit()
        return True
    except Exception, e:              ## 请记住这个try: except Exception, e:  的好习惯,能帮助你运行不了的时候debug,不要学那个粗心家伙
        print str(e) 
        return False

if __name__=="__main__":
    fortune = os.popen('fortune')
    twitter = fortune.read()
    html = """
                    <html>
      <head></head>
      <body>
        <p>Hi!<br>
           How are you?<br>
           Here is the <a href="http://www.python.org">link</a> you wanted.
        </p>
        <b>有没有看到,这是一封经过全自动化python脚本发送的电子邮件</b>
        <br>
        <p>
        <h2>每次随机一句</h2>
        <font color="magenta">
        <b>
    """     
    html = html + twitter + """
      </b>
      </font>
      </body>
    </html>
    """
    if send_a_mail('xxxxxx@126.com','xxxxxx@qq.com','smtp.126.com','mypassword','全自动发电子邮件脚本', html):
        print "mail sent"
    else:
        print "mail not sent"
原文地址:https://www.cnblogs.com/spaceship9/p/3207743.html