python发邮件(一)

通过python发邮件的步骤:
  • 邮箱开通了SMTP服务,并设置了授权码(可以登陆第三方客户端)
  • 构建收发件人,主题,内容
  • 创建一个smtp对象,连接到smtp服务器,登陆邮件,发送邮件,关闭stmp对象
 
163邮箱测试一直报554错误代码。以下代码基于QQ邮箱
 
[root@web sendemial]# cat test.py
#!/usr/bin/env python
#coding:utf8

import codecs
import sys
import os
import smtplib
from email.mime.text import MIMEText
from email.header import Header

class SendEmail(object):
    def __init__(self, sender, sendto, subject, subtype, filename):
        self.sender = sender
        self.sendto = sendto
        self.subject = subject
        self.filename = filename
        self.subtype = subtype
        self.smtpserver = 'smtp.qq.com'
        self.username = self.sender
        self.password = 'xxxxx'
        self._init()

    def _init(self):
        if not os.path.exists(self.filename):
            print ('{0} is not exist, program exiting.....')
            sys.exit()

    def readContent(self):
        with codecs.open(self.filename, 'rb', encoding='utf-8') as fd:
            return fd.read()

    def buildHeader(self):
        self.msg = MIMEText(self.readContent(), self.subtype, 'utf-8')        //创建消息对象
        self.msg['Subject'] = Header(self.subject, 'utf-8')                   //构建请求头信息,第一个参数必须为字符串
        self.msg['From'] = Header(self.sender, 'utf-8')
        self.msg['To'] = Header(','.join(self.sendto), 'utf-8')

    def send(self):
        self.buildHeader()
        try:
            sm = smtplib.SMTP_SSL()                                         //创建smtp对象,qq邮箱强制走ssl
            sm.connect(self.smtpserver, 465)                                //smtp服务器走465端口
            sm.login(self.username, self.password)
            sm.sendmail(self.sender, self.sendto, self.msg.as_string())         //调用对象的发送邮件方法
        except Exception as e:
            print (e)
        finally:
            sm.quit()


if __name__ == '__main__':       
    sender = 'xxxx@qq.com'
    sendto = ['xxx@qq.com', 'xxxx']
    subject = 'web聊天室'
    subtype = 'plain'
    filename = 'content.txt'
    sendEmail = SendEmail(sender, sendto, subject, subtype, filename)
    sendEmail.send()

 

需要注意的地方:
  1. 创建消息对象
In [27]: help(email.mime.Text.MIMEText)
Help on class MIMEText in module email.mime.text:

class MIMEText(email.mime.nonmultipart.MIMENonMultipart)
 |  Class for generating text/* type MIME documents.
 | 
 |  Method resolution order:
 |      MIMEText
 |      email.mime.nonmultipart.MIMENonMultipart
 |      email.mime.base.MIMEBase
 |      email.message.Message
 | 
 |  Methods defined here:
 | 
 |  __init__(self, _text, _subtype='plain', _charset='us-ascii')
 |      Create a text/* type MIME document.
 |     
 |      _text is the string for this message object.                          //第一个参数为消息对象(文本内容)
 |     
 |      _subtype is the MIME sub content type, defaulting to "plain".         //发送文本:_subtype='plain'(默认);如果邮件内容含html代码:_subtype='html'
 |     
 |      _charset is the character set parameter added to the Content-Type     //字符集默认为ascii
 |      header.  This defaults to "us-ascii".  Note that as a side-effect, the
 |      Content-Transfer-Encoding header will also be set.

 

2. 构建头部信息

In [28]: help(email.Header.Header)
Help on class Header in module email.header:

class Header
 |  Methods defined here:
 | 
 |  __eq__(self, other)
 |      # Rich comparison operators for equality only.  BAW: does it make sense to
 |      # have or explicitly disable <, <=, >, >= operators?
 | 
 |  __init__(self, s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')
 |      Create a MIME-compliant header that can contain many character sets.

  s may be a byte string or a Unicode string            //第一个参数必须是字符串或者unicode编码

 

  1. 选择邮箱和smtp服务器的问题
 
qq邮箱默认走ssl,所以创建的smtp对象必须要支持加密传输,且需要指定port=465
 
  1. 发送邮件
In [30]: help(smtplib.SMTP_SSL)
Help on class SMTP_SSL in module smtplib:

class SMTP_SSL(SMTP)
 |  This is a subclass derived from SMTP that connects over an SSL encrypted
 |  socket (to use this class you need a socket module that was compiled with SSL
 |  support). If host is not specified, '' (the local host) is used. If port is
 |  omitted, the standard SMTP-over-SSL port (465) is used. keyfile and certfile
 |  are also optional - they can contain a PEM formatted private key and
 |  certificate chain file for the SSL connection.
 | 
 |  Methods defined here:
 | 
 |  __init__(self, host='', port=0, local_hostname=None, keyfile=None, certfile=None, timeout=<object object>)

.......

 |  sendmail(self, from_addr, to_addrs, msg, mail_options=[], rcpt_options=[])
 |      This command performs an entire mail transaction.
 |     
 |      The arguments are:
 |          - from_addr    : The address sending this mail.                               //邮件发送地址
 |          - to_addrs     : A list of addresses to send this mail to.  A bare           //邮件接收地址,必须为一个列表,列表的元素是收件邮件邮箱,如果只有一个收件人,可以不用列表,直接使用字符串 e.g. '736821063@qq.com'
 |                           string will be treated as a list with 1 address.
 |          - msg          : The message to send.                                        //需要发送的消息,这里指的是通过Header类创建的携带头部信息的消息对象
 |          - mail_options : List of ESMTP options (such as 8bitmime) for the
 |                           mail command.
 |          - rcpt_options : List of ESMTP options (such as DSN commands) for
 |                           all the rcpt commands.

 

5. 如果上面的代码发送失败,试试下面的代码,主要是创建消息对象的方式不同

[root@web sendemial]# cat test1.py
#!/usr/bin/env python
#coding:utf8

import codecs
import sys
import os
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

class SendEmail(object):
    def __init__(self, sender, sendto, subject, subtype, filename):
        self.sender = sender
        self.sendto = sendto
        self.subject = subject
        self.filename = filename
        self.subtype = subtype
        self.smtpserver = 'smtp.qq.com'
        self.username = self.sender
        self.password = 'xxxxx'
        self._init()

    def _init(self):
        if not os.path.exists(self.filename):
            print ('{0} is not exist, program exiting.....')
            sys.exit()

    def readContent(self):
        with codecs.open(self.filename, 'rb', encoding='utf-8') as fd:
            return fd.read()

    def buildHeader(self):
        self.msg = MIMEMultipart()
        self.msg['from'] = self.sender
        self.msg['to'] = ','.join(self.sendto)            //构建头部信息,跟上面一样,值必须为字符串
        self.msg['subject'] = self.subject
        txt = MIMEText(self.readContent(), self.subtype, 'utf-8')
        self.msg.attach(txt)

    def send(self):
        self.buildHeader()
        try:
            sm = smtplib.SMTP_SSL()
            sm.connect(self.smtpserver, 465)
            sm.login(self.username, self.password)
            sm.sendmail(self.sender, self.sendto, self.msg.as_string())
        except Exception as e:
            raise e
            print (e)
        finally:
            sm.quit()


if __name__ == '__main__':       
    sender = 'xxxx'
    sendto = ['xxxx', 'xxxx']
    subject = 'debugging'
    subtype = 'plain'
    filename = 'content.txt'
    sendEmail = SendEmail(sender, sendto, subject, subtype, filename)
    sendEmail.send()

 

转载于:https://www.cnblogs.com/tobeone/p/8241043.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值