• 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/

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

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

  • 相关阅读:
    vue基础知识
    git的创建使用
    使用express搭建服务器框架
    日常训练
    今日收获
    今日收获
    今日收获
    今日收获
    今日收获
    今日收获
  • 原文地址:https://www.cnblogs.com/erjuan/p/6425471.html
Copyright © 2020-2023  润新知