zoukankan      html  css  js  c++  java
  • Python之smtplib发送邮件 by二卷


    SMTP 基础知识

    1.SMTP 的会话方式

    1.邮件直接投递
    发送邮件给XXX@163.com,直接链接163.com的邮件服务器,把邮件给XXX@163.com


    2.验证过后发信
    你有YYY@126.com邮箱,发送邮件给XXX@163.com,要先连接126.com的smtp服务器,然后认证,之后在把要发到163.com的信件投到126.com上,126.com会帮你把信投递到163.com。


    email使用语法

    1.创建简单的纯文本文件

    from email.mime.text import MIMEText
    msg = MIMEText('hello world!', 'plain', 'utf-8') #返回MIMEText对象
    #'hello world!'为邮件正文;'plain'是MIME的子类型;
    #一定要用utf-8编码保证多语言兼容性
    

    注:MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。例:text/plain 就是一个MIME类型,text是类型 & plain是子类型,文件设置为纯文本的形式,浏览器在获取到这种文件时并不会对其进行处理。


    smtplib使用语法

    1.创建python的SMTP对象

    import smtplib
    
    smtpObj = smtplib.SMTP( [host [, port [,local_hostname]]] )
    #host: SMTP 服务器主机,可以指定主机的ip地址或者域名(可选)
    #port: 有host 参数则要指定SMTP服务使用的端口号,一般为25
    #local_hostname:SMTP在本机上,只需指定服务器地址为 localhost
    

    2.python的SMTP对象使用sendmail方法发送邮件

    smtpObj.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])
    #from_addr: 邮件发送者地址
    #to_addrs: 字符串列表,邮件发送地址
    #msg: 发送消息,字符串,格式是smtp协议中定义的格式
    


    实例

    1.primer(发送纯文本)

    #!/usr/bin/python
    # -*- encoding:utf-8 -*-
    
    from email.mime.text import MIMEText
    import smtplib
    from email.header import Header
    from email.utils import parseaddr, formataddr
    
    '''
    这里采用的是间接方式,就是上述的验证后发信。如果你有一个163.com的邮箱,
    想发送给一个126.com的邮箱,先链接163.com的邮箱服务器,登录你的邮箱后,
    再通过1163.com的邮箱服务器发送邮件给126.com的邮箱。
    注:通过第三方的邮件服务器发送邮件比较通用,你自己的服务器发邮件很容易被接收方判定为垃圾邮件
    '''
    def _format_addr(s): #定义一个不能被其他文件import的函数,主要用于处理邮件的编码问题
        name, addr = parseaddr(s) #如果是erjuan<erjuan.163.com>,则name就是erjuan, addr就是erjuan.163.com,注意邮箱格式要对
        #变成准确的邮件需要的编码
        return formataddr(( 
            Header(name, 'utf-8').encode(), 
            addr.encode('utf-8') if isinstance(addr, unicode) else addr))
    
    from_addr = raw_input('From: ') #输入你需要登录认证邮箱的地址,就是你自己的邮箱
    password = raw_input('Password: ') #你邮箱的密码
    smtp_server = raw_input('SMTP server: ')# 输入SMTP服务器地址,如果你用是163邮箱,那么就是:smtp.163.com
    to_addr = raw_input('To: ')# 输入收件人地址
    
    emailContent = MIMEText('hello world!', 'plain', 'utf-8')
    #关于Header见官网https://docs.python.org/2/library/email.header.html?highlight=email.head#module-email.header
    emailContent['From'] = _format_addr(u'二卷<'+from_addr+'>')
    emailContent['To'] = _format_addr(u'You<'+to_addr+'>')
    #emailContent['From'] = Header("二卷<erjuan@163.com>", 'utf-8')
    #emailContent['To'] =  Header("You<xxxx@126.com", 'utf-8')#直接这样使用,会出现乱码问题
    emailContent['Subject'] = Header('来自二卷的邮件哦', 'utf-8').encode()
    
    server = smtplib.SMTP(smtp_server, 25)# 连接邮件服务器,SMTP协议默认端口是25
    #server = smtplib.SMTP('localhost') 使用这个话的时候一般需要你的机器上安装有发送邮件的程序,例如sendmail
    #server.set_debuglevel(1)#打印流程
    server.login(from_addr, password)#登录你的邮箱
    server.sendmail(from_addr, [to_addr], emailContent.as_string())#发送邮件
    server.quit()
    

    结果展示

    Bug
    如果出现smtplib.SMTPDataError: (554, …… 这样的报错是因为你的真实的邮件地址和你在From和to中填写的不一致

    2.primer+1(发送html)

    只需要修改primer中发送文本的emailContent = MIMEText(……)这个语句,把plain换成html,然后第一个参数写上html的语句

    emailContent = MIMEText('<html><body><h1>Hello world!</h1>' +
        '<a href="http://www.baidu.com">百度</a>' +
        '</body></html>', 'html', 'utf-8')
    

    结果展示

    3.advance(发送附件)

    发送带附件的方法蛮多的,这里介绍一个简单的,需要创建MIMEMultipart()实例,比较简单的是使用都用MIMEApplication来添加附件,MIMEApplication默认子类型是application/octet-stream(表示二进制文件,根据其后缀进行处理)

    #!/usr/bin/python
    # -*- encoding:utf-8 -*-
    
    from email.mime.text import MIMEText
    from email.mime.image import MIMEImage
    from email.mime.multipart import MIMEMultipart
    import smtplib
    from email.header import Header
    from email.utils import parseaddr, formataddr
    
    
    def _format_addr(s):
        name, addr = parseaddr(s)
        return formataddr(( 
            Header(name, 'utf-8').encode(), 
            addr.encode('utf-8') if isinstance(addr, unicode) else addr))
    
    from_addr = raw_input('From: ')
    password = raw_input('Password: ')
    smtp_server = raw_input('SMTP server: ')
    to_addr = raw_input('To: ')
    
    #创建一个带附件的实例
    emailContent = MIMEMultipart()
    emailContent['From'] = _format_addr(u'二卷<'+from_addr+'>')
    emailContent['To'] = _format_addr(u'You<'+to_addr+'>')
    emailContent['Subject'] = Header('来自二卷的邮件哦', 'utf-8').encode()
    
    #邮件中的文本信息
    emailText = MIMEText("This email has attachment", 'plain', 'utf-8')
    emailContent.attach(emailText)
    
    #邮件中的附件信息,一般来说会判断一下附件的文件类型,我们这里是图片,就不判断了
    img = open('picture.png', 'rb')
    attachment = MIMEImage(img.read())
    img.close()
    emailContent.attach(attachment)
    
    server = smtplib.SMTP(smtp_server, 25)
    server.login(from_addr, password)
    server.sendmail(from_addr, [to_addr], emailContent.as_string())
    server.quit()
    

    结果展示

    3.advance+1(在正文中显示图片)

    正文中的图片用html语言来引用附件中的,只需要把上面的代码稍作修改
    这个方法的话附件还是存在的

    #!/usr/bin/python
    # -*- encoding:utf-8 -*-
    
    from email.mime.text import MIMEText
    from email.mime.image import MIMEImage
    from email.mime.multipart import MIMEMultipart
    import smtplib
    from email.header import Header
    from email.utils import parseaddr, formataddr
    
    
    def _format_addr(s):
        name, addr = parseaddr(s)
        return formataddr(( 
            Header(name, 'utf-8').encode(), 
            addr.encode('utf-8') if isinstance(addr, unicode) else addr))
    
    from_addr = raw_input('From: ')
    password = raw_input('Password: ')
    smtp_server = raw_input('SMTP server: ')
    to_addr = raw_input('To: ')
    
    #创建一个带附件的实例
    emailContent = MIMEMultipart()
    emailContent['From'] = _format_addr(u'二卷<'+from_addr+'>')
    emailContent['To'] = _format_addr(u'You<'+to_addr+'>')
    emailContent['Subject'] = Header('来自二卷的邮件哦', 'utf-8').encode()
    
    #邮件中的文本信息
    emailText = MIMEText('<html><body><h1>Hello world!</h1>' +
        '<p>邮件文本中有图片</p><p><img src="cid:pp"></p>' +
        '</body></html>', 'html', 'utf-8')
    emailContent.attach(emailText)
    
    #邮件中的附件信息,一般来说会判断一下附件的文件类型,我们这里是图片,就不判断了
    img = open('picture.png', 'rb')
    attachment = MIMEImage(img.read())
    #给你的附件命名,这里叫pp,这样在上面的html中好引用,用cid
    attachment.add_header('Content-ID', 'pp')
    img.close()
    emailContent.attach(attachment)
    
    server = smtplib.SMTP(smtp_server, 25)
    server.login(from_addr, password)
    server.sendmail(from_addr, [to_addr], emailContent.as_string())
    server.quit()
    

    结果展示





    -------------------------------------------我是求打赏的分割线-------------------------------------------

    大海中的一颗星辰,天空中的一枚卷花

    作者:二卷

    出处:http://www.cnblogs.com/erjuan/

    本文版权归二卷和博客园共有,欢迎转载,但未经二卷同意必须保留此段声明哦,且在文章页面位置给出二卷的原文连接

    有错误的话也可以联系二卷指正哦(鞠躬)

  • 相关阅读:
    [置顶] windows player,wzplayerV2 for windows
    wzplayer 近期将会支持BlackBerry和WinPhone8
    wzplayerEx for android(真正硬解接口,支持加密的 player)
    ffmpeg for ios 交叉编译 (支持i686 armv7 armv7s) 包含lame支持
    ffmpeg for ios 交叉编译 (支持i686 armv7 armv7s) 包含lame支持
    编译cegcc 0.59.1
    wzplayer 近期将会支持BlackBerry和WinPhone8
    wzplayerEx for android(真正硬解接口,支持加密的 player)
    windows player,wzplayerV2 for windows(20140416)更新
    编译cegcc 0.59.1
  • 原文地址:https://www.cnblogs.com/erjuan/p/6425471.html
Copyright © 2011-2022 走看看