zoukankan      html  css  js  c++  java
  • python3发送邮件(有附件)

    python3发送邮件(有附件)

    代码一:

    import smtplib
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    from email.mime.image import MIMEImage
    from email.utils import formatdate
    import os

    #设置登录及服务器信息
    mail_host = 'smtp.vcredit.com'
    mail_user = 'h***@vcredit.com'
    mail_pass = 'h****'
    sender = 'h***@vcredit.com'
    receivers = ['p****@vcredit.com']

    #设置eamil信息
    #添加一个MIMEmultipart类,处理正文及附件
    message = MIMEMultipart()
    message['From'] = sender
    message['To'] = receivers[0]
    message['Subject'] = '测试'
    message['Date'] = formatdate( )
    #推荐使用html格式的正文内容,这样比较灵活,可以附加图片地址,调整格式等
    with open('abc.html','r') as f:
    content = f.read()
    #设置html格式参数
    part1 = MIMEText(content,'html','utf-8')

    basename = os.path.basename("report.txt")
    #添加一个txt文本附件
    with open('report.txt','r')as h:
    content2 = h.read()
    #设置txt参数
    part2 = MIMEText(content2,'plain','utf-8')

    #附件设置内容类型,方便起见,设置为二进制流
    part2['Content-Type'] = 'application/octet-stream'
    #设置附件头,添加文件名
    part2['Content-Disposition'] = 'attachment;filename=%s' % basename

    #解决中文附件名乱码问题
    # part2.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', basename))

    #添加照片附件
    with open('1.png','rb')as fp:
    picture = MIMEImage(fp.read())
    #与txt文件设置相似
    picture['Content-Type'] = 'application/octet-stream'
    picture['Content-Disposition'] = 'attachment;filename="1.png"'
    #将内容附加到邮件主体中
    message.attach(part1)
    message.attach(part2)
    message.attach(picture)

    #登录并发送
    try:
    # smtpObj = smtplib.SMTP()
    # smtpObj.connect(mail_host,25)
    #需要SSL认证
    smtpObj = smtplib.SMTP_SSL(mail_host)

    smtpObj.login(mail_user,mail_pass)
    smtpObj.sendmail(sender,receivers,message.as_string())
    print('success')
    smtpObj.quit()
    except smtplib.SMTPException as e:
    print('error',e)

    参考链接:http://mp.weixin.qq.com/s/X8i4b2HlU7HAlZLeGVnl0A

    经验证使用代码一从公司的Outlook邮箱发送到Outlook邮箱是没有问题的,但是当附件的名称为中文的时候,收到的邮件的附件名称为

    研究了很长时间,不知道怎么解决。。。

    用代码一从公司的Outlook邮箱发送到QQ邮箱,QQ邮箱收不到邮件(原因未知),不过可以使用代码二发送到QQ邮箱,并且不存在未命名附件和乱码的问题;但是发送到公司的Outlook邮箱不管是否为中文名称的附件都存在未命名附件的问题。

    解决方法:针对代码二可以使用Foxmail收取Outlook的邮件,这样不会出现未命名附件和乱码的问题

    代码二:

    '''发送带附件的邮件'''
    from email import encoders
    from email.mime.text import MIMEText
    from email.utils import formatdate
    from email.mime.multipart import MIMEMultipart
    from email.mime.base import MIMEBase
    from email.header import Header
    import smtplib
    import os.path

    From = "p****@vcredit.com"

    #多个收件人用逗号隔开
    To = "9*****@qq.com, aa@aa.com"

    acc = 'dd@dd.com, eeg@ee.com'
    file_name = "测试.png"

    server = smtplib.SMTP("smtp.vcredit.com")
    server.login("p****@vcredit.com","p*****") #仅smtp服务器需要验证时

    # 构造MIMEMultipart对象做为根容器
    main_msg = MIMEMultipart()

    # 构造MIMEText对象做为邮件显示内容并附加到根容器
    text_msg = MIMEText("this is a test text to text mime")
    main_msg.attach(text_msg)

    # 构造MIMEBase对象做为文件附件内容并附加到根容器
    contype = 'application/octet-stream'
    maintype, subtype = contype.split('/', 1)

    # 读入文件内容并格式化
    data = open(file_name, 'rb')
    file_msg = MIMEBase(maintype, subtype)
    file_msg.set_payload(data.read( ))
    data.close( )
    encoders.encode_base64(file_msg)

    # 设置附件头
    basename = os.path.basename(file_name)
    #解决中文附件名乱码问题
    file_msg.add_header('Content-Disposition', 'attachment', filename=('gbk', '', basename))
    main_msg.attach(file_msg)

    # 设置根容器属性
    main_msg['From'] = From
    main_msg['To'] = To

    main_msg['Cc'] = acc 
    main_msg['Subject'] = Header("邮件测试","utf-8")
    main_msg['Date'] = formatdate( )

    # 得到格式化后的完整文本
    fullText = main_msg.as_string( )

    # 用smtp发送邮件
    try:

    #发送给多人、同时抄送给多人,发送人和抄送人放在同一个列表中
      server.sendmail(From, To.split(',') + acc.split(','), fullText)
    finally:
      server.quit()

    代码三:

    Python发送图片|文本|word|pdf格式的邮件

    import os, pickle
    import smtplib 
    import mimetypes 
    from email.mime.multipart import MIMEMultipart 
    from email.mime.base import MIMEBase 
    from email.mime.text import MIMEText 
    from email.mime.audio import MIMEAudio 
    from email.mime.image import MIMEImage 
    from email.encoders import encode_base64
    import email

    def dumpPickle(data, saveLocation, fileName):
        os.chdir(saveLocation) #文件存放的路径
        with open(fileName, 'wb') as f:
            pickle.dump(data, f) #导入数据data到文件f中
            print('save data: %s successful' % fileName)

    def loadPickle(loadLocation, fileName):
        os.chdir(loadLocation) #文件读取的路径
        with open(fileName, 'rb') as f:
            return pickle.load(f) #读取数据

    def sendMail(subject, recipient, text, *attachmentFilePaths): 
        '''发送邮件函数:参数(邮件主题,邮件内容,邮件附件(可多选))''' 
        msg = MIMEMultipart()  # 发送附件时需调用 MIMEMultipart类,创建 MIMEMultipart,并添加信息头

        '''
    MIME邮件的基本信息、格式信息、编码方式等重要内容都记录在邮件内的各种域中,域的基本格式:{域名}:{内容},域由域名后面跟“:”再加上域的信息内容构成,一条域在邮件中占一行或者多行,
    域的首行左侧不能有空白字符,比如空格或者制表符,占用多行的域其后续行则必须以空白字符开头。域的信息内容中还可以包含属性,属性之间以“;”分隔,属性的格式如下:{属性名称}=”{属性值}”。   
        '''
        msg['From'] = sender 
        msg['To'] = ";".join(recipient)
        msg['Subject'] = subject 
        msg.attach(MIMEText(text)) 

        for attachmentFilePath in attachmentFilePaths:  #判断添加哪些附件
            msg.attach(getAttachment(attachmentFilePath))  #如果入参给定附件文件,使用attach 发放添加msg头信息
        try:
            mailServer = smtplib.SMTP('smtp.qq.com',587)  # 连接腾讯邮件的服务器;SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式
            mailServer.ehlo()  # 使用starttls 方法必须先 ehlo 判断是否是同一个地址。。。
            mailServer.starttls()  # 以下SMTP都会加密;Put the SMTP connection in TLS (Transport Layer Security) mode. All SMTP commands that follow will be encrypted.
            mailServer.ehlo()  # You should then call ehlo() again.
            mailServer.login(sender, password)  # 登录邮箱
            mailServer.sendmail(sender, recipient, msg.as_string())  # 发送邮件(发件人,收件人,发送内容)
            mailServer.close() # 关闭邮件发送服务
            print('Sent email to %s successfully' % recipient)
        except Exception as e:
            print('sendEmai failed %s' % e)

    """part = MIMEApplication(open('foo.mp3','rb').read())
    part.add_header('Content-Disposition', 'attachment', filename="foo.mp3")
    msg.attach(part) """     

    def getAttachment(attachmentFilePath):  # 获取附件,参数:文件路径
        contentType, encoding = mimetypes.guess_type(attachmentFilePath)  # 根据 guess_type方法判断文件的类型和编码方式

        if contentType is None or encoding is not None:  # 如果根据文件的名字/后缀识别不出是什么文件类型
            contentType = 'application/octet-stream'   # 使用默认类型,usable for a MIME content-type header.

        mainType, subType = contentType.split('/', 1)  # 根据contentType 判断主类型与子类型
        file = open(attachmentFilePath, 'rb') 

        if mainType == 'text':  # 根据主类型不同,调用不同的文件读取方法
            attachment = MIMEBase(mainType, subType)  # A subclass of MIMENonMultipart, the MIMEText class is used to create MIME objects of major type text.
            attachment.set_payload(file.read())  # Set the entire message object’s payload(负载) to payload.
            encode_base64(attachment)  # Encodes the payload into base64 form and sets the Content-Transfer-Encoding header to base64.       
        elif mainType == 'message': 
            attachment = email.message_from_file(file)  # 使用message_from_file方法,Return a message object structure tree from an open file object
        elif mainType == 'image':  # 图片
            attachment = MIMEImage(file.read())  #A subclass of MIMENonMultipart, the MIMEImage class is used to create MIME message objects of major type image.
        #elif mainType == 'audio':  # 音频
            #attachment = MIMEAudio(file.read(), _subType=subType)  #A subclass of MIMENonMultipart, the MIMEAudio class is used to create MIME message objects of major type audio.

        else: 
            attachment = MIMEBase(mainType, subType)  # The MIMEBase class always adds a Content-Type header (based on _maintype, _subtype, and _params), and a MIME-Version header (always set to 1.0).
            attachment.set_payload(file.read())  # Set the entire message object’s payload(负载) to payload.
            encode_base64(attachment)  # Encodes the payload into base64 form and sets the Content-Transfer-Encoding header to base64.  

        file.close() 
        """
    Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。Content-disposition其实可以控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名,
    文件直接在浏览器上显示或者在访问时弹出文件下载对话框。 content-disposition = "Content-Disposition" ":" disposition-type *( ";" disposition-parm ) 。   
        """
    #     attachment.add_header('Content-Disposition', 'attachment',   filename=os.path.basename(attachmentFilePath))
        attachment.add_header('Content-Disposition', 'attachment',   filename=('gb2312', '', os.path.basename(attachmentFilePath)))  #Content-Disposition为属性名 disposition-type是以什么方式下载,如attachment为以附件方式下载 disposition-parm为默认保存时的文件名
        return attachment 

    #需要先执行dumpPickle函数生成senderInfo.txt文件
    #dumpPickle("发件人邮箱?发件人邮箱密码?['收件人邮箱']", os.path.basename('.'), "senderInfo.txt")
    if __name__ == "__main__":
        #qq邮箱登录的时候密码需要换成授权码
        senderInfo = loadPickle(os.path.basename('.'), "senderInfo.txt")
        sender = senderInfo.split("?")[0] #发件人邮箱
        password = senderInfo.split("?")[1] #发件人邮箱密码
        recipient = senderInfo.split("?")[2] #收件人邮箱
        recipient = [recipient[2:-2]] #将string格式的"['收件人邮箱']"转换成['收件人邮箱']
        sendMail('邮件主题', recipient, '发送格式:.jpg, .pdf, .docx, .txt', 'error_jpg.jpg', '律***.pdf', '函****.docx', '测试.txt')

    对于Outlook邮箱还是存在上面说的问题,建议可以使用Foxmail邮箱收取相关邮件。 

    参考链接:

    http://blog.csdn.net/ck3207/article/details/51823905

    http://blog.csdn.net/biboshouyu/article/details/53338277

  • 相关阅读:
    小波变化与小波降噪
    非正态分布数据转换成正态分布
    使用pyinstaller将pyqt5打包成exe格式
    使用PyQt5嵌入matplotlib,实现根据界面输入数值更换显示的matplotlib图形
    python异常机制、多进程与PyQt5中的QTimer、多线程
    PyQt5中使用QTimer定时刷新:当要执行可能会超过设定时间的代码
    解决pyinstaller打包sklearn等库出现的问题: 提示failed to execute script xxx
    数据分析实例-MovieLens 1M 数据集
    机器学习各类算法的优缺点
    pandas时间序列
  • 原文地址:https://www.cnblogs.com/sammy1989/p/6137928.html
Copyright © 2011-2022 走看看