python 基础知识记录
说明:
电子邮件
邮件发送流程:
SMTP
协议发送给邮件
可以送纯文本、HTML、带附件的邮件。
说明:
-
email
构造邮件;smtplib
发送邮件;邮箱 smtp服务器地址 问题描述 @163.com smtp.163.com qq->163 发送成功 @qq.com smtp.qq.com 163->qq 被识别垃圾邮箱 -
属于第三方登陆,需要授权码。列举
qq邮箱
获取授权码
-
第一次简单发送,被认为是垃圾邮件了,发送失败;
163 被退性错误码说明 -
邮件加入相关信息:发送邮件主题、发件人信息、收件人信息; 添加之后可以发出去了,但是被
QQ邮箱
识别为垃圾邮件,退回来了。
然后去扣扣邮箱将发送邮箱(163邮箱)设置为白名单可以接受到了。
-
加密传输,创建
SSL
安全连接。
发送一个纯文本邮件
# 邮件类型指定为纯文本格式
from email.mime.text import MIMEText
# 需要加入邮件主题信息
from email.header import Header
from email.utils import parseaddr,formataddr
import smtplib
# 1. 发送信息前发送人信息编辑
# addr= input("Email:")
addr= "**@qq.com"
# password = input("Passworld:") 邮箱授权码
password = "***"
# 收件人地址
# to_addr = input("To:")
to_addr = "**@163.com"
# 邮箱服务地址 , qq邮箱 ;
smtp_server = "smtp.qq.com"
#2. 邮件信息构造
# 格式化邮件主题信息
def formate_addr(s):
name,addr = parseaddr(s)
return formataddr((Header(name,"utf-8").encode(),addr))
# 纯文本信息
msg = MIMEText('hello world , you are my shushine!','plain','utf-8')
# 设置邮件发送人、收件人信息
msg["From"] = formate_addr('来自关注者 <%s>' % addr)
msg["To"] = formate_addr("Hello [%s]" % to_addr)
# 设置邮件主题
msg["Subject"] = Header('大哥,最近还好吗?',"utf-8").encode()
#3. 新建一个smtp服务
server = smtplib.SMTP(smtp_server,25)
# 加密发送
server.starttls()
# 发布日志跟踪打印
server.set_debuglevel(1)
# 登陆发送邮件 、 认证
server.login(addr,password)
# 信息发送给收件人
server.sendmail(addr,[to_addr],msg.as_string())
# 结束退出服务
server.quit()
发送附件
附件包括文档、图片。
在发布纯文本的邮件基础上,增加发布附件。代码增量书写。
说明:
- 邮件主体格式:文本呢、附件、图片、HTML、应用程序、视频等。
MIMEMultipart
可对其他特定格式进行组合,进行发送。- 设置文件头部信息,不加入也可以发不成功,可能是为了规范吧:
mime.add_header('Content-Disposition', 'attachment', filename='test.png') mime.add_header('Content-ID', '<0>') mime.add_header('X-Attachment-Id', '0')
# 加入邮件类型:文本/多部分
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 其他邮件分类类型的基类,可以处理任意类型
from email.mime.base import MIMEBase
# 对带有文件的类型进行编码
from email import encoders
# 信息构造 , 消息主题类型为多形式格式
msg = MIMEMultipart()
# msg = MIMEText('hello world , you are my shushine!','plain','utf-8')
msg["From"] = formate_addr('来自关注者 <%s>' % addr)
msg["To"] = formate_addr("Hello [%s]" % to_addr)
msg["Subject"] = Header('大哥,最近还好吗?',"utf-8").encode()
# 可以加入文本信息
msg.attach(MIMEText('hello world , you are my shushine!','plain','utf-8'))
# 加入附件文件信息
# 读取当前目录下的一张图片 , 以字节码读取,网络传输
with open("./test.png","rb") as f:
# 设置文件基本信息
mime = MIMEBase("image",'png',filename="test.png")
# 加入文件头信息
# mime.add_header('Content-Disposition', 'attachment', filename='test.png')
# mime.add_header('Content-ID', '<0>')
# mime.add_header('X-Attachment-Id', '0')
# 读取文件
mime.set_payload(f.read())
# 文件编码 base 64
encoders.encode_base64(mime)
msg.attach(mime)
发送html邮件
以文本格式发送html
字符串、第二个参数指定解析格式为html
;
说明:
MIMEText
发布,设置第二个参数为html
格式- 直接读取目录下的
test.html
文件进行发布。
# 可以加入文本信息
# msg.attach(MIMEText('hello world , you are my shushine!','plain','utf-8'))
with open("./test.html","r",encoding="utf-8") as f:
msg.attach(MIMEText(f.read(),'html','utf-8'))
示例结果:
发送图片
可以直接将作为附件的图片加入到正文中。
说明:
-
发送
html
文件格式,将图片引入。
-
使用附件中的图片,填充到
<img src=''>
中.cid:num
来表示附件;num
表示第几个附件未能测试成功
num
从 0 开始; -
读取图片文件转
base64
,插入img
中;
说明- 注意编码
base64
- 加前缀
data:image/png;base64,
stream
需要解码stream.decode()
# base64 编码 import base64 # 读取文件, 字节码转 base64 with open("./test.png","rb") as f: # base64 前缀,指定文件格式 affix = "data:image/png;base64," # 转 stream = base64.b64encode(f.read()) msg.attach(MIMEText('''<html> <head></head><body> <h1>hello world</h1> <img src="'+affix+stream.decode()+'"> </body></html>''','html','utf-8'))
效果展示:
- 注意编码
POP3接收邮件
python
模块poplib
实现接收邮件,并通过email
模块解析成可读文件。
说明:
msg = Parser().parsestr(content)
解析出来的是email.message.Message
对象,调用相关API
# 邮件信息解析
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
# 邮件接收
import poplib
# 调试
import pdb
# 收件人邮箱信息用于登陆
addr= "***@qq.com"
# 授权码
password = "***"
# 邮箱服务地址
pop_server = "pop.qq.com"
# 创建服务,登陆接收邮件
server = poplib.POP3(pop_server)
# 调试信息
server.set_debuglevel(1)
# 邮箱欢迎信息
print(server.getwelcome().decode('utf-8'))
# 身份认证
server.user(addr)
server.pass_(password)
# stat() 获取邮件数量及占用空间
print("Email list: num %s , size %s " % server.stat())
# list() 获取列表信息(response,[mes_num octets ...],octets)
resp,nums,octets = server.list()
# 打印输出
# print(nums[1:10])
# retr() 按索引号获取每一份信息,设置可见标识;返回参数:(response,[line ...],octets)
index = len(nums)
resp,lines,octets = server.retr(index)
# lines 标识原始邮件信息的每一行
# 合并后解码
content = b'\r\b'.join(lines).decode('utf-8')
# 解析内容为 Message 对象
# pdb.set_trace()
msg = Parser().parsestr(content)
print(msg.as_string())
msg.as_string()
可以打印出相关信息,只是消息内容被编码。
# 消息体解析
还在努力中…