Python模块探秘 Smtplib发送带有各种附件的邮件

简介: 这两天对Python的邮件模块比较感兴趣,于是就查了查资料。同时在实际的编码过程中也遇到了各种各样的问题。下面我就来分享一下我与smtplib的故事。前提条件我的上一篇博文里面讲解了,发送邮件必须的条件。

这两天对Python的邮件模块比较感兴趣,于是就查了查资料。同时在实际的编码过程中也遇到了各种各样的问题。下面我就来分享一下我与smtplib的故事。


前提条件

我的上一篇博文里面讲解了,发送邮件必须的条件。这里同样是适用的。大致就是要开启邮箱的SMPT/POP服务等等。如果不明白,可以看看发送纯文本邮件。里面讲的还不错。 :-)

核心知识点

因为今天主要讲解的是如何发送带有附件的邮件,那么核心肯定是附件了。怎么才能发附件呢?

其实我们换个思路,就不难理解了。因为我们发送邮件,经过了应用层–>> 传输层–>> 网络层–>>数据链路层–>>物理层。这一系列的步骤,全都变成了比特流了。所以无论是纯文本,图片,亦或是其他类型的文件。在比特流的面前,都是平等的。所以我们发送附件,也是按照发送纯文本的模式来做就行,只不过加上一些特殊的标记即可。


\# 首先是xlsx类型的附件
xlsxpart = MIMEApplication(open('test.xlsx', 'rb').read())
xlsxpart.add_header('Content-Disposition', 'attachment', filename='test.xlsx')
msg.attach(xlsxpart)

\# jpg类型的附件
jpgpart = MIMEApplication(open('beauty.jpg', 'rb').read())
jpgpart.add_header('Content-Disposition', 'attachment', filename='beauty.jpg')
msg.attach(jpgpart)

\# mp3类型的附件
mp3part = MIMEApplication(open('kenny.mp3', 'rb').read())
mp3part.add_header('Content-Disposition', 'attachment', filename='benny.mp3')
msg.attach(mp3part)

经过这三小段的代码,想必你已经很清楚了吧。无非就是使用MIMEApplication进行包装一下,然后设置一下内容。最后添加到邮件内容。就是这几步,就搞定了。

完整的代码

# coding:utf-8

#    __author__ = 'Mark sinoberg'
#    __date__ = '2016/5/26'
#    __Desc__ = 实现发送带有各种附件类型的邮件

import urllib, urllib2
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication

username = '156408XXXXX@163.com'
password = 'XXXXXXXX'
sender = username
receivers = ','.join(['10643XXXX2@qq.com'])

# 如名字所示: Multipart就是多个部分
msg = MIMEMultipart()
msg['Subject'] = 'Python mail Test'
msg['From'] = sender
msg['To'] = receivers

# 下面是文字部分,也就是纯文本
puretext = MIMEText('我是纯文本部分,')
msg.attach(puretext)

# 下面是附件部分 ,这里分为了好几个类型

# 首先是xlsx类型的附件
xlsxpart = MIMEApplication(open('test.xlsx', 'rb').read())
xlsxpart.add_header('Content-Disposition', 'attachment', filename='test.xlsx')
msg.attach(xlsxpart)

# jpg类型的附件
jpgpart = MIMEApplication(open('beauty.jpg', 'rb').read())
jpgpart.add_header('Content-Disposition', 'attachment', filename='beauty.jpg')
msg.attach(jpgpart)

# mp3类型的附件
mp3part = MIMEApplication(open('kenny.mp3', 'rb').read())
mp3part.add_header('Content-Disposition', 'attachment', filename='benny.mp3')
msg.attach(mp3part)

##  下面开始真正的发送邮件了
try:
    client = smtplib.SMTP()
    client.connect('smtp.163.com')
    client.login(username, password)
    client.sendmail(sender, receivers, msg.as_string())
    client.quit()
    print '带有各种附件的邮件发送成功!'
except smtplib.SMTPRecipientsRefused:
    print 'Recipient refused'
except smtplib.SMTPAuthenticationError:
    print 'Auth error'
except smtplib.SMTPSenderRefused:
    print 'Sender refused'
except smtplib.SMTPException,e:
    print e.message

验证结果

没有什么比来张图片更有说服力的了。如图
带有各种附件的邮件结果图

错误总结

我遇到的错误如下:

D:\Software\Python2\python.exe E:/Code/Python/MyTestSet/mail/withappedix.py
Traceback (most recent call last):
  File "E:/Code/Python/MyTestSet/mail/withappedix.py", line 51, in <module>
    client.sendmail(sender, receivers, msg.as_string())
  File "D:\Software\Python2\lib\email\message.py", line 137, in as_string
    g.flatten(self, unixfrom=unixfrom)
  File "D:\Software\Python2\lib\email\generator.py", line 83, in flatten
    self._write(msg)
  File "D:\Software\Python2\lib\email\generator.py", line 115, in _write
    self._write_headers(msg)
  File "D:\Software\Python2\lib\email\generator.py", line 164, in _write_headers
    v, maxlinelen=self._maxheaderlen, header_name=h).encode()
  File "D:\Software\Python2\lib\email\header.py", line 410, in encode
    value = self._encode_chunks(newchunks, maxlinelen)
  File "D:\Software\Python2\lib\email\header.py", line 370, in _encode_chunks
    _max_append(chunks, s, maxlinelen, extra)
  File "D:\Software\Python2\lib\email\quoprimime.py", line 97, in _max_append
    L.append(s.lstrip())
AttributeError: 'list' object has no attribute 'lstrip'

Process finished with exit code 1

我的解决办法是
receiver parameter was list type. either it should be list converted to string using join method or if it is a single recipient, then pass it as a string only

是的,就是receivers = ','.join(['10XXXXXXXX@qq.com'])。这样就搞定了。

也许,你遇到的错误不是我这个,那么也不用担心,我这里有一份比较齐全的错误码对照表。你可以对照着你的错误码来查找具体的错误原因。这样有的放矢,效率会更高一点的。

在编码的过程中,我也是遇到了很多意想不到的错误。而这些错误的错误码对我们来说是很有用的。这对我们测试代码以及找到其中出错的原因和有帮助。

企业退信的错误码对照表

(^__^) 嘻嘻……。这下字体够大了吧。

目录
相关文章
|
5天前
|
Java 程序员 开发者
Python的gc模块
Python的gc模块
|
8天前
|
数据采集 Web App开发 JavaScript
python-selenium模块详解!!!
Selenium 是一个强大的自动化测试工具,支持 Python 调用浏览器进行网页抓取。本文介绍了 Selenium 的安装、基本使用、元素定位、高级操作等内容。主要内容包括:发送请求、加载网页、元素定位、处理 Cookie、无头浏览器设置、页面等待、窗口和 iframe 切换等。通过示例代码帮助读者快速掌握 Selenium 的核心功能。
42 5
|
6天前
|
Python
SciPy 教程 之 SciPy 模块列表 16
SciPy教程之SciPy模块列表16 - 单位类型。常量模块包含多种单位,如公制、质量、角度、时间、长度、压强、体积、速度、温度、能量、功率和力学单位。示例代码展示了力学单位的使用,如牛顿、磅力和千克力等。
11 0
|
7天前
|
JavaScript Python
SciPy 教程 之 SciPy 模块列表 15
SciPy 教程之 SciPy 模块列表 15 - 功率单位。常量模块包含多种单位,如公制、质量、时间等。功率单位中,1 瓦特定义为 1 焦耳/秒,表示每秒转换或耗散的能量速率。示例代码展示了如何使用 `constants` 模块获取马力值(745.6998715822701)。
11 0
|
7天前
|
JavaScript Python
SciPy 教程 之 SciPy 模块列表 15
SciPy教程之SciPy模块列表15:单位类型。常量模块包含多种单位,如公制、质量、角度、时间、长度、压强、体积、速度、温度、能量、功率和力学单位。功率单位以瓦特(W)表示,1W=1J/s。示例代码展示了如何使用`constants`模块获取马力(hp)的值,结果为745.6998715822701。
12 0
|
12天前
|
安全 数据处理 开发者
Python中的多线程编程:从入门到精通
本文将深入探讨Python中的多线程编程,包括其基本原理、应用场景、实现方法以及常见问题和解决方案。通过本文的学习,读者将对Python多线程编程有一个全面的认识,能够在实际项目中灵活运用。
|
7天前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
12天前
|
弹性计算 安全 小程序
编程之美:Python让你领略浪漫星空下的流星雨奇观
这段代码使用 Python 的 `turtle` 库实现了一个流星雨动画。程序通过创建 `Meteor` 类来生成具有随机属性的流星,包括大小、颜色、位置和速度。在无限循环中,流星不断移动并重新绘制,营造出流星雨的效果。环境需求为 Python 3.11.4 和 PyCharm 2023.2.5。
|
5天前
|
数据处理 Python
从零到英雄:Python编程的奇幻旅程###
想象你正站在数字世界的门槛上,手中握着一把名为“Python”的魔法钥匙。别小看这把钥匙,它能开启无限可能的大门,引领你穿梭于现实与虚拟之间,创造属于自己的奇迹。本文将带你踏上一场从零基础到编程英雄的奇妙之旅,通过生动有趣的比喻和实际案例,让你领略Python编程的魅力,激发内心深处对技术的渴望与热爱。 ###