肥宅钓鱼网
当前位置: 首页 钓鱼百科

python发送本地邮件(Python3之发送和读取邮件)

时间:2023-07-25 作者: 小编 阅读量: 1 栏目名: 钓鱼百科

python中发送邮件使用的模块有smtplib和email:1.使用smtplib模块进行发送邮件;2.使用email模块来添加发送的邮件内容。故若待测试邮箱不允许使用非SSL和非TLS频道通信时,则无法使用smtp.SMTP方式来创建客户端对象。to_addr:收件人地址,包括收件人和抄送人。多个收件人时to_addr参数为列表,单个收件人时to_addr参数可以为列表或字符串。

01

发送邮件

发送邮件使用SMTP协议【Simple Mail Transfer Protocol简单的邮件传输协议】,SMTP协议是SMTP客户端与SMTP服务器之间的通信协议。

python中发送邮件使用的模块有smtplib和email:

1.使用smtplib模块进行发送邮件;

2.使用email模块来添加发送的邮件内容。

1. smtplib模块

导入模块:import smtplib

1.1. 创建SMTP对象

smtplib.SMTPsmtplib.SMTP_SSL:均可以用来创建SMTP对象;

smtplib.SMTP_SSL:使用安全加密的SSL协议连接到SMTP服务器;

smtplib.SMTP:没有进行安全加密。

故若待测试邮箱不允许使用非SSL和非TLS频道通信时,则无法使用smtp.SMTP方式来创建客户端对象。

【查看邮箱的通信方式:邮箱设置菜单中,查看邮箱的接收服务器和发送服务器信息。】

如:腾讯企业邮箱接收服务器:imap.exmail.qq.com(使用SSL,端口号993)发送服务器:smtp.exmail.qq.com(使用SSL,端口号465)

smtplib.SMTP(host,port,local_hostname,timeout,source_address)

smtplib.SMTP_SSL(host, port, local_hostname, keyfile, certfile, timeout, source_address, context)

创建SMTP对象。

host:SMTP发送服务器主机

port:SMTP服务器端口号

1.2. SMTP对象操作

login(user, password, *, initial_response_ok=True)

SMTP对象登录

user:授权登录的用户名

password:授权登录的密码

sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[])

SMTP对象发送邮件

from_addr:发件人地址,字符串类型。

to_addr:收件人地址,包括收件人和抄送人。

多个收件人时to_addr参数为列表,单个收件人时to_addr参数可以为列表或字符串。

msg:要发送的信息

quite终止SMTP会话

2. 发送邮件的实例

2.1. 添加邮件内容,包括收件人、抄送人、正文、附件

from email.mime.multipart import MIMEMultipartfrom email.header import Headerfrom email.mime.text import MIMETextfrom email.mime.image import MIMEImageimport osclass EmailContent: def __init__(self, senderAdr, emailSubject, toReceivers, ccReceivers): # 邮件对象 self.msg = MIMEMultipart # 添加发件人头 self.msg['From'] = Header("测试""<"senderAdr">", 'utf-8') # 添加收件人 if isinstance(toReceivers, str): self.msg["To"] = toReceivers elif isinstance(toReceivers, list): self.msg['To'] = ";".join(toReceivers) # 添加抄送人 if isinstance(ccReceivers, str): self.msg["Cc"] = ccReceivers elif isinstance(ccReceivers, list): self.msg["Cc"] = ";".join(ccReceivers) # 添加邮件主题 self.msg['Subject'] = Header(emailSubject, "utf-8") def addBody(self, bodyType): """ 添加不同的邮件正文的实例 1. body为字符串:(如)"这是一个邮件正文内容" 2. body为html格式的字符串:(如)"<div><p>第一段</p><p>&nbsp;第二段</p></div>" 3. body正文中包含有图片: """ if bodyType == "string": body = "这是一个邮件正文内容" mimeText = MIMEText(body, "plain", "utf-8") self.msg.attach(mimeText) elif bodyType == "html": body = "<div><p>第一段</p><p>&nbsp;第二段</p></div>" mimeText = MIMEText(body, "html", "utf-8") self.msg.attach(mimeText) elif "image" in bodyType: imagefile = "E://log//test.png" imageId = os.path.split(imageFile)[1] # 添加内容 body = ''' <p>测试图片为:</p> <p><img src="http://img.studyofnet.comcid:{imageId}"></p> '''.format(imageId=imageId) mimeText = MIMEText(body, "html", "utf-8") self.msg.attach(mimeText) # 读取图片,并设置图片id用于邮件正文引用 with open(imageFile, "rb") as fp: mimeImage = MIMEImage(fp.read) mimeImage.add_header("Content-ID", imageId) self.msg.attach(mimeImage) def addAttachment(self, attachmentName): """ 添加附件 :return: """ file = "E://log//test.txt" # file = "E://log//test.zip" # file = "E://log//test.png" filePath, fileName = os.path.split(file) print("fileName =", fileName) enclosure = MIMEText(open(file, 'rb').read, 'base64', 'utf-8') enclosure['Content-Type'] = 'application/octet-stream' if attachmentName == "英文": enclosure['Content-Disposition'] = 'attachment; filename="%s"' % fileName elif attachmentName == "中文": enclosure.add_header("Content-Disposition", "attachment", filename=("gbk", "", fileName)) self.msg.attach(enclosure)

2.2. 发送邮件

import smtplibdef SendEmail: """发送邮件""" # SMTP的服务器信息 smtpHost = "smtp.exmail.qq.com" sslPort = 465 senderAdr = "xx@xx.cn" senderPwd = "XXXX" # 创建SMTP对象 smtpServer = smtplib.SMTP_SSL(smtpHost, sslPort) # # 设置debug模块 # smtpServer.set_debuglevel(True) # 登录 smtpServer.login(senderAdr, senderPwd) # 添加邮件内容 toReceivers = ["a@xx.cn", "b@xx.cn"] ccReceivers = ["d@xx.cn", "e@xx.cn"] toAddrs = toReceiversccReceivers emailSubject = "这是个编程技术圈自动发送的邮件" emailContent = EmailContent(senderAdr, emailSubject, toReceivers, ccReceivers) emailContent.addBody("html") emailContent.addAttachment("英文") message = emailContent.msg # 发送 smtpServer.sendmail(senderAdr, toAddrs, message.as_string) # 终止SMTP会话 smtpServer.quitSendEmail

02

读取邮件

收取邮件使用POP3协议;

解析邮件:需要将收取的邮件转化为email.message.Message对象,再使用email模块解析内容。

1. 读取邮件的实例

1.1. 获取某封邮件的对象

import poplibfrom email.parser import Parser"""POP的服务器信息"""popHost = "pop.exmail.qq.com"userAdr = "xx@xx.cn"userPwd = "xxxxx"""" 创建POP3对象,添加用户名和密码"""pop3Server = poplib.POP3(popHost)pop3Server.user(userAdr)pop3Server.pass_(userPwd)"""获取邮件数量和占用空间"""messageCount, mailboxSize = pop3Server.stat"""获取邮件请求返回状态码、每封邮件的字节大小(b'第几封邮件 此邮件字节大小')、"""response, msgNumOctets, octets = pop3Server.list""" 获取任意一封邮件的邮件对象【第一封邮件的编号为1,而不是0】"""msgIndex = random.randint(1,messageCount)print(msgIndex)# 获取第msgIndex封邮件的信息response, msgLines, octets = pop3Server.retr(msgIndex)# msgLines中为该邮件的每行数据,先将内容连接成字符串,再转化为email.message.Message对象msgLinesToStr = b"\r\n".join(msgLines).decode("utf8", "ignore")messageObject = Parser.parsestr(msgLinesToStr)print(messageObject)""" 终止POP3服务"""pop3Server.quit

1.2. 解析邮件对象

1.2.1. 获取邮件日期

msgDate = messageObject["date"]print(msgDate)

1.2.2. 获取邮件发件人实名、邮箱地址

获取邮件实名时,名称一般是加密的,此时就需要对头文件进行解码才可获取它的实际内容

from email.header import decode_headerdef decodeMsgHeader(header): """ 解码头文件 :param header: 需解码的内容 :return: """ value, charset = decode_header(header)[0] if charset: value = value.decode(charset) return value

from email.utils import parseaddrsenderContent = messageObject["From"]# parseaddr函数返回的是一个元组(realname, emailAddress)senderRealName, senderAdr = parseaddr(senderContent) # 将加密的名称进行解码 senderRealName = decodeMsgHeader(senderRealName) print(senderRealName)print(senderAdr)

1.2.3. 获取邮件主题

获取的邮件的主题也是加密的,此时就需要对头文件进行解码才可获取它的实际内容

msgHeader = messageObject["Subject"]# 对头文件进行解码msgHeader = decodeMsgHeader(msgHeader )print(msgHeader)

1.2.4. 获取邮件正文

一封邮件的正文内容,可能是由几部分构成,每部分的格式不同。

"""获取邮件正文内容"""msgBodyContents = if messageObject.is_multipart: # 判断邮件是否由多个部分构成 messageParts = messageObject.get_payload # 获取邮件附载部分 for messagePart in messageParts: bodyContent = decodeBody(messagePart) if bodyContent: msgBodyContents.append(bodyContent)else: bodyContent = decodeBody(messageObject) if bodyContent: messageBodyContents.append(bodyContent)print(msgBodyContents)

def decodeBody(msgPart): """ 解码内容 :param msgPart: 邮件某部分 """ contentType = msgPart.get_content_type # 判断邮件内容的类型,text/html textContent = "" if contentType == 'text/plain' or contentType == 'text/html': content = msgPart.get_payload(decode=True) charset = msgPart.get_charset if charset is None: contentType = msgPart.get('Content-Type', '').lower position = contentType.find('charset=') if position >= 0: charset = contentType[position8:].strip if charset: textContent = content.decode(charset) return textContent

1.2.5. 获取邮件附件

邮件附件名为中文时,需借助头文件解码方式进行解码,否则会为乱码。

messageAttachments = if messageObject.is_multipart: # 判断邮件是否由多个部分构成 messageParts = messageObject.get_payload # 获取邮件附载部分 for messagePart in messageParts: name = messagePart.get_param("name") # 名字存在,则表示此部分为附件 if name: fileName = decodeMsgHeader(name) # 解码 messageAttachments.append(fileName)else: name = messageObject.get_param("name") if name: fileName = decodeMsgHeader(name) # 解码 messageAttachments.append(fileName)print(messageAttachments)

2. 读取邮件时遇到的问题

2.1. 提示“poplib.error_proto: line too long”

File "XXX/EmailInfo.py", line 22, in getMessageObject return parser.Parser.parsestr(b"\n".join(self.popServer.retr(i)[1]).decode("utf8", "ignore")) File "/usr/local/lib/python3.6/poplib.py", line 248, in retr return self._longcmd('RETR %s' % which) File "/usr/local/lib/python3.6/poplib.py", line 183, in _longcmd return self._getlongresp File "/usr/local/lib/python3.6/poplib.py", line 168, in _getlongresp line, o = self._getline File "/usr/local/lib/python3.6/poplib.py", line 130, in _getline raise error_proto('line too long')poplib.error_proto: line too long

POP3对行长度做了限制,默认为_MAXLINE = 2048,故若是邮件超过此长度就会提示“poplib.error_proto: line too long”。

解决方案:在读取邮件代码中重新定义最大行长度,即给poplib._MAXLINE设置新值。

import poplibpoplib._MAXLINE=20480

- end -

    推荐阅读
  • 袋鼠的资料(袋鼠的简介)

    我们一起去了解并探讨一下这个问题吧!袋鼠的资料袋鼠是一种属于袋鼠目的有袋动物,主要分布于澳大利亚大陆和巴布亚新几内亚的部分地区。不同种类的袋鼠在澳大利亚各种不同的自然环境中生活,从凉性气候的雨林和沙漠平原到热带地区。袋鼠是跳得最高最远的哺乳动物。这个词源自GuuguYimidhirr,后来袋鼠这个词被约瑟夫·班克斯在詹姆斯·库克的第一次航海旅行中命名。

  • 鹅怎么烧才好吃(烧老鹅怎么做)

    我们一起去了解并探讨一下这个问题吧!鹅怎么烧才好吃鹅1000g,葱姜各10g,八角5g,油,生抽,料酒各10ml。鹅肉洗净切块,冷水下锅焯水后捞起。锅内倒油烧至5成热,加入八角和生姜片爆香。倒入鹅肉翻炒均匀,加入料酒,生抽,加入开水。大火烧开5分钟后转小火煮至鹅肉熟,装盘后,撒上葱花即可。

  • 我国过失损坏交通工具犯罪刑事立案追诉标准是如何规定

    过失损害交通工具罪,造成严重后果的才构成犯罪。本罪侵犯的客体是交通运输安全。侵害的对象是正在使用的火车、汽车、电车、船只、航空器等大型现代化交通工具。

  • 老公说离婚后妻子怎么挽回婚姻 老公想离婚妻子如何挽回

    无论你针对离异是否作为不在乎,但实际上,夫妻感情破裂针对每一个心态过程都是导致重挫,以致于她们做了错误的行为。显而易见,离婚挽回中这种可伶女性的作法总是是火上加油,让本来早已厌烦他们的老公进一步憎恶他们,增加离婚之后挽回老公的通过率。减肥瘦身、运动健身、塑性变形、瑜伽健身是更改人的身型,头型、服饰、妆面是更改人的容貌,知识是更改人的气场。

  • 汤姆索亚历险记好句摘抄(关于汤姆索亚历险记值得摘抄的好句)

    汤姆索亚历险记好句摘抄?汤姆索亚历险记好句摘抄当悲伤的水流入稳重的山,水这可怜儿的悲伤也勾起了山的悲伤,于是他们的心一起碎了;水把头埋入地下,山却把心的碎片一块块收好。汤姆又撒谎骗了姨妈,但姨妈很高兴,只想,这慌撒的好,我喜欢这样的谎话。这就是汤姆向这个暴戾的老师的复仇。开始审问坟地上的谋杀案,波特就要被绞刑了,汤姆去作证,印第安乔逃跑了,波特获得释放。

  • 抗痘血泪史经验帖(八一八我20年的控油抗痘血泪史)

    LZ现在32岁,不错,你没看错,和痘痘抗争的历史已经达到了20年。也是大油田得福音。控油的产品依然无效。该出的油还是得出,一“克”都不能少。LZ皮非常厚,不容易过敏。4)屈臣氏绿茶面膜作为一款预防的产品,很不错,一天到2天贴一张,在那期间,基本上没有痘痘的。一方面我怀孕前的3年使用了一套产品,另一方面是因为怀孕改变了身体激素状况。坚持使用了2年半,总共用了将近22组。又过了2个多月,痘痘几乎就没有了。

  • 家里有老鼠怎么能彻底消灭(怎么彻底消灭老鼠)

    家里有老鼠怎么能彻底消灭搞好家庭环境卫生:老鼠喜欢生活在脏乱差的环境中,依靠人们生活中废弃的有机物生存。而保持环境整洁,是减少老鼠生存机会最省钱的办法。室内灭鼠要针对老鼠的“交通”路线实施隔离。灭鼠期间管好水、食源,坚壁清野。一周后发现毒饵未吃但仍有鼠活动,可将毒饵再作调整,给老鼠取食的机会。老鼠夹:将鼠夹与墙面垂直,饵料一头靠墙,夹子与墙的距离约为2~3厘米。

  • 鹧鸪天什么意思(鹧鸪天简单介绍)

    以下内容大家不妨参考一二希望能帮到您!鹧鸪天什么意思鹧鸪天,词牌名,又名“思佳客”“思越人”“醉梅花”“半死梧”“剪朝霞”等。定格为晏几道《鹧鸪天·彩袖殷勤捧玉钟》,此调双调五十五字,前段四句三平韵,后段五句三平韵。上阕第三四句、下阕第一二句一般要求对仗。代表作有苏轼的《鹧鸪天·林断山明竹隐墙》等。

  • 郑州市经开区公租房报名摇号配租公示表

    经开区公共租赁住房报名摇号配租公示表发布时间:2022年9月21日经开区本次轮侯供应房源为大雅苑项目,其中一居室129套,二居室25套,针对已取得经开区公租房保障资格号未实物配租的保障对象进行报名摇号配租,有报名意愿的家庭可在微信易住宝程序上进行报名。

  • 树蛙对人体有害吗(树蛙有毒吗)

    树蛙对人体有害吗很多树蛙品种是无毒的,比如大部分体表呈绿色的树蛙就是无毒的。不过有一些树蛙的身体表面有毒性,但这些树蛙的毒性并不是特别强烈,在接触到人体之后人体的反应各不相同,有些人没有反应,有些皮肤比较敏感的人则会有一点不舒服的感觉。但总体来看反应不会太强。另外还有一些树蛙本身的毒性就是非常强烈的,从颜色来看,很多颜色五彩斑斓的品种就是有剧毒的,在碰到之后一定要小心。