邮件历史。。。
-
起源
-
就是通信的一个发展,懒得打字了省略了,以后再查吧
-
-
管理程序
-
一些让邮件普及的邮件公司
-
邮件的工作流程
-
MUA(MailUserAgent)邮件用户代理
-
MTA(MailTransferAgent)邮件传输代理
-
MDA(MailDeliveryAgent)邮件投递代理
-
流程
-
MUT->MTA
-
qq MTA->...........................->sina MTA
-
sina MTA->.........................->sina MDA
-
sina MDA->MUA(FoxMail/outlook)邮件下载到本地电脑
-
-
编写程序
-
发送 MUA->MTA 协议
-
接收 MTA->MDA 协议
-
-
准备工作
-
注册邮箱
-
第三方邮箱进行设置
-
进入设置中心
-
取得授权码
-
案例07发送纯文本邮件‘
-
import smtplib from email.mime.text import MIMEText #MIMEText的主要参数有3个 #1。邮件内容 #2。MIME子类型,在这里用plain代表text格式的文件 #3.邮件的编码格式 msg = MIMEText('这是一封文本格式的邮件','plain','utf-8') #发送email的地址,需要更改为对应的邮件地址 from_addr = 'xxxxx@qq.com' #授权密码,大多数的邮箱在使用第三方软件时,都需要验证密钥,这里不是指邮箱的密码 from_pwd = 'XXXXXXXXXXX' #收件人 to_addr = 'xxxxx@qq.com' #输入smtplib服务器地址 #此处根据不同的邮件服务商有不同的值 #现在基本任何一家邮件服务商在开启第三方邮件的时候都需要开启服务 #TX QQ邮箱的smtplib地址时smtplib.qq.com smtp_srv = 'smtplib.qq.com' try: srv = smtplib.SNTP_SSL(smtp_srv.encode(),465) #这里的465时QQ邮箱的端口 #登陆邮箱,任何的邮箱在使用之前都必须的登陆 srv.login(from_addr,from_pwd) #发送邮件 #三参数,发送地址,接受的地址(必须时list格式),发送内容时字符串格式 srv.sendmail(from_addr,[to_addr],msg.as_String()) srv.quit() except Exception as e: print(e)
-
-
-
Python for mail
-
SMTP协议负责发送邮件
-
使用Email模块构建邮件-纯文本案例V07
-
HTML格式邮件发送
-
准备HTML代码作为内容
-
把邮件的subtype设为html
-
发送
-
案列V08
-
import smtplib from email.mime.text import MIMEText #MIMEText的主要的三个参数 #1。邮件内容 #2。MIME子类型的格式 这里时HTML所以是html #3.邮件的编码格式 msg_content = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>这是一封HTML格式的邮件</h1> </body> </html> """ #发送邮件的地址 from_addr = 'XXXXX@qq.com' #发送邮件的密码 from_pwd = 'XXXXXXXXXXx' #收件人 to_addr = 'XXXXX@qq.com' #输入SMTP服务器地址 smtp_srv = 'smtp.qq.com' try: srv = smtplib.SMTP_SSL(smtp_srv.encode(),465) #登陆邮箱 srv.login(from_addr,from_pwd) #发送邮件 srv.sendemail = (from_addr,[to_addr],msg_content.as_toString()) srv.quit() except Exception as e: print(e)
-
-
发送带附件的邮件
-
可以看作有一个文本邮件和一个附件的合体
-
需要使用MIMEltaipart格式构建
-
添加一个MIMEBase或者MEME text作为附件
-
案列V09
-
import smtplib from email.mime.text import MIMEText from email.mime.text import MIMEBase,MIMMultipart #构建基础邮件时使用 mail_mul = MIMEMulipart() #构建邮件正文 main_text = MIMEText("这是邮件的正文",'plain','utf-8') #把构建的正文附加到邮件中 mail_mul.attach(mail_text) #构建附件,需要从本地读入 #打开一个本地文件 with open('a.txt','rb') as f: s = f.read() #设置附件的MIME文件名 m = MIMEText(s,'base64','utf-8') m['Content-Type'] = 'application.octet-stream' #需要注意的 #1.attachment后的分号时英文状态 #2.filename 后面需要英文包裹,注意外面的引号错开 m['Content-Dispostion'] = 'attachment;filename="a.txt"' #添加MIMEMultipation mail_mul.attach(m) #发送邮件 from_addr = 'XXXXX@qq.com' from_pwd = 'XXXXXXXXx' to_addr = 'XXXXXXX@qq,com' smtp_srv = 'sntp.qq.com' try: srv = smtplib.SMTP_SSL(smtp_srv.encode(),465) #登陆邮箱 srv.load(from_addr,from_pwd) srv.sendmail(from_addr,[to_addr],mail_mul.as_string()) srv.quit() except Exception as e: print(e)
-
-
添加邮件头,抄送等信息
-
mail['From'] 表示发送者的信息,包括姓名和邮件
-
mail['To'] 表示接收者信息,包括姓名和邮件地址
-
mail['Subject']表示摘要或者主题信息
-
案例V10
-
-
同时支持html和text格式
-
构建一个MIMEMultipart格式的邮件
-
MIMEMultipart的subtype设置成alterbalive
-
添加html 文件和text文件
-
import smtplib from email.mime.text import MIMEText from email,mime.multipart import MIMEMUltipart #构建一个MIMEMultipart邮件 msg = MIMEMultapart('alternative') #构建一个HTML格式的邮件内容 html_content = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>这是一封HTML格式的邮件</h1> </body> </html> """ msg_html = MIMEText(html_content,'html','utf-8') msg.attach(msg_html) #构建一个文本格式的邮件 msg_text = MIMEText("这是文本格式的邮件",'plain','utf-8') msg.attach(msg_text) from_addr = 'XXXXXXx@q.com' from_pwd = 'XXXXX' to_addr = "XXXXx@qq.com" smtp_srv = 'smtp.qq.com' try: srv = smtplib.SMTP_SSL(smtp_srv.encode(),465) srv.login(from_addr,from_pwd) srv_sendmail(from_addr,[to_addr],msg.as_tostring()) srv.quit() except Exception as e: print(e)
-
-
使用smtplib模块发送邮件
-
-
POP3协议接受邮件
-
本质上讲是从MDA到MTA的一个过程
-
从MDA下载下来的是一个完整的邮件结构体,需要解析才能的带每个具有
-
步骤:
-
1.用poplib下载邮件结构体原始内容
-
1.准备相应的内容(邮件的内容,密码。pop3实例)
-
2.身份验证
-
3.一般会先得到邮箱内邮件的整体列表
-
4.根据相应的序号,得到某一封信的数据流
-
5.利用解析函数进行解析出相应的邮件结构体
-
-
2.emai解析邮件的具体内容
-
案例V12
-
#导入相关的包 #poplib负责相关的MDA到MUA的下载 import poplib from email.parser import Parser from email.header import decode_header from email.utils import parseaddr #得到邮件的原始内容 #这个过程主要看负责从MDA带MUA的下载并且使用Parse粗略的解析 def getMsg(): #准备相应的信息 email = '1033808656@qq.com' #邮箱的授权码 pwd = 'pwd' #pop3的服务器地址 默认端口995 pop3_srv = 'pop.qq.com' #SSL代表安全通道 srv = poplib.POP3_SSL(pop3_srv) #user代表Email地址 srv.user(email) #pass_代表密码 srv.pass_(pwd) #一下操作根据业务内容具体使用 #stat返回邮件的数量和占用的空间 #注意stat返回一个tuple格式 msgs,counts = srv.stat() print("messages:{0},Size{1}".format(msgs,counts)) #list返回所有的邮件编号列表 #malis返回所有邮件编号列表 rsp,mails,octets = srv.list() #可以查看返回mails列表类似 print(mails) #获取最新一封邮件,注意,邮件的索引号从1开始,最新的邮件索引号最高 index = len(mails) #retr 负责返回一个具体索引号的一封信的内容,此内容不具有可读性 #lines 存储邮件的最高原始文本的每一行 rsp,lines,octets = srv.retr(index) #获取整个邮件的原始文本 msg_count = b'\r\n'.join(lines).decode('utf8') #解析出邮件的整个结构体 #参数时解码后的邮件整体 msg = Parser().parsestr(msg_count) #关闭链接 srv.quit() return msg # #详细解释得到的邮件内容 #msg表示邮件的原始内容 #idnent代表的是邮件的嵌套层级 def parseMsg(msg,indent=0): ''' 1.邮件可能是完全嵌套 2.邮件只有一个From,To,Subject之类的信息 :param msg: :param indent: 描述邮件里面的几个邮件的MIMEXXX类型的内容,展示的时候进行缩进 :return: ''' #想办法提取头部信息 #只有在第一层的邮件中才会有相关信息内容 #此内容只有一个 if indent == 0: for header in ['From','To','Subject']: #使用get可以避免如果没有相关关键字报错的可能性 #如果没有关键字“From"在使用msg["From"]时会报错 value = msg.get(header,'') if value: #Subject中的内容直接解码就可以,他是字符串类型 if header == 'Subject': value = decodeStr(value) #如果是From和To字段,则内容的大概是‘我的邮箱<xxxxx@qq.com>’这种格式 else: hdr,addr = parseaddr(value) name = decodeStr(hdr) #最终的返回类型如“我的邮箱是<xxxxx@qq.com>” value = "{0}<{1}>.".format(name,addr) print("{0},{1}:{2}".format(indent,header,value)) #接下来关注邮件内容本身 #邮件内容中,有可能是multipart类型,也有可能是普通邮件类型 #下面的解析使用递归的方法 if (msg.is_multipart()): #如果是multipart类型则调用递归解释 #得到多部分邮件的一个基础邮件部分 parts = msg.get_payload() #enumerate函数是内置函数 #作用是将一个列表,此处是parts,生成一个有索引和parts原内容生成的列表 #例如:enumerate(['a','b','c'])结果是:[(1,'a'),(2,'b'),(3,'c')] for n,part in enumerate(parts): #一个字符串乘以一个数字的意思就是对这个字符串进行n倍扩展 #例如("aa"*2) = 'aaaa' print("{0}spart:{1}".format(' '*indent,n)) parseMsg(part,indent+1) else:#基础类型 #get_content_type是系统函数,得到内容的类型 content_type = msg.get_content_type() #text/plain,或者是text/html是固定值 if content_type == 'text/plain' or content_type == 'text/html': content = msg.get_payload(decode=True) charset = gussCharset(msg) if charset: content = content.decode(charset) print("{0}text:{1}".format(indent,content)) else:#不是文本内容,因该是附件 print('{0}Attachment:{1}'.format(indent,content_type)) def decodeStr(s): ''' s代表一封邮件中的from,to,Subject中的任意一项 对s进行解码,解码是通过编码的逆过程 :param s: :return: ''' value,charset = decode_header(s)[0] #charset完全可能为空 if charset: #如果指定编码,则用指定的编码格式进行解码 value = value.decode(charset) return value def gussCharset(msg): ''' 猜测邮件的编码格式 :param msg: :return: ''' #调用现成的函数 charset = msg.get_charset() if charset is None: #找到相应的内容类型转换成小写 content_type = msg.get("Content-Type","").lower() pos = content_type.find('charset=') if pos > 0: #如果包含charset,则内容为charset=XXX charset = content_type[pos+8:].strip() return charset if __name__ == '__main__': #得到邮件的原始内容 msg = getMsg() print(msg) #精确解析邮件的内容 parseMsg(msg,0)
-
-
-
-