Python-Net 编程
网络编程
网络:
网络协议: 一套规则
网络模型:
七层模型-七层-理论
物理层
数据链路层
网络层
传输层
会话层
表示层
应用层
四层模型-实际应用
链路层
网络层
传输层
引用层
每一层都有相应的协议负责交换信息或者协同工作
TCP/IP 协议族
IP 地址:负责在网络上唯一定位一个机器
IP 地址分 ABCDE 类
是由四个数字段组成,每个数字段的取值是 0-255
192.168.xxx.xxx: 局域网 ip
127.0.0.1: 本机
IPv4, IPv6
端口
范围: 0-65535
知名端口:0-1023
非知名端口:1024-
ICP/UDP 协议
UDP: 非安全的不面向链接的传输
安全性差
大小限制 64kb
没有顺序
速度快
TCP
基于链接的通信
SOCKET 编程
socket(套接字):是一个网络通信的端点,能实现不同主机的进程通信,网络大多基于 socket 通信
通过 IP+端口定位对方并发送消息的通信机制
分为 UDP 和 TCP
客户端 Client,发起访问的一方
服务器端 Server,接受访问的一方
UDP 编程
Server 端流程
建立 socket,socket 是负责具体通信的一个实例
绑定,为创建的 socket 指派固定的端口和 ip 地址
接受对方发送内容
给对方发送反馈,此步骤为非必须步骤
Client 端流程
建立通信的 socket
发送内容到指定服务器
接受服务器给定的反馈内容
服务器案例 v01
'''
Server端流程
1. 建立socket,socket是负责具体通信的一个实例
2. 绑定,为创建的socket指派固定的端口和ip地址
3. 接受对方发送内容
4. 给对方发送反馈,此步骤为非必须步骤
'''
# socket模块负责socket编程
import socket
# 模拟服务器的函数
def serverFunc():
# 1. 建立socket
# socket.AF_INET: 使用ipv4协议族
# socket.SOCK_DGRAM: 使用UDP通信
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2. 绑定ip和port
# 127.0.0.1: 这个ip地址代表的是机器本身
# 7852: 随机指定的端口号
# 地址是一个tuple类型,(ip, port)
addr = ("127.0.0.1", 7852)
sock.bind(addr)
# 3. 接受对方消息
# 等待方式为死等,没有其他可能性
# recvfrom接受的返回值是一个tuple,前一项表示数据,后一项表示地址
# 参数的含义是缓冲区大小
# rst = sock.recvfrom(500)
data, addr = sock.recvfrom(500)
print(data)
print(type(data))
# 发送过来的数据是bytes格式,必须通过解码才能得到str格式内容
# decode默认参数是utf8
text = data.decode()
print(type(text))
print(text)
# 给对方返回的消息
rsp = "Ich hab keine Hunge"
# 发送的数据需要编码成bytes格式
# 默认是utf8
data = rsp.encode()
sock.sendto(data, addr)
if __name__ == '__main__':
print("Starting server.........")
serverFunc()
print("Ending server...........")
- 客户端案例v02
import socket
'''
Client端流程
1. 建立通信的socket
2. 发送内容到指定服务器
3. 接受服务器给定的反馈内容
'''
def clientFunc():
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
text = "I love you"
# 发送的数据必须是bytes格式
data = text.encode()
# 发送
sock.sendto(data, ("127.0.0.1", 7852))
data, addr = sock.recvfrom(200)
data = data.decode()
print(data)
if __name__ == '__main__':
clientFunc()
- 服务器程序要永久运行,一般用死循环处理
- 改造的服务器版本v03
'''
Server端流程
1. 建立socket,socket是负责具体通信的一个实例
2. 绑定,为创建的socket指派固定的端口和ip地址
3. 接受对方发送内容
4. 给对方发送反馈,此步骤为非必须步骤
'''
# socket模块负责socket编程
import socket
# 模拟服务器的函数
def serverFunc():
# 1. 建立socket
# socket.AF_INET: 使用ipv4协议族
# socket.SOCK_DGRAM: 使用UDP通信
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2. 绑定ip和port
# 127.0.0.1: 这个ip地址代表的是机器本身
# 7852: 随机指定的端口号
# 地址是一个tuple类型,(ip, port)
addr = ("127.0.0.1", 7852)
sock.bind(addr)
# 3. 接受对方消息
# 等待方式为死等,没有其他可能性
# recvfrom接受的返回值是一个tuple,前一项表示数据,后一项表示地址
# 参数的含义是缓冲区大小
# rst = sock.recvfrom(500)
data, addr = sock.recvfrom(500)
print(data)
print(type(data))
# 发送过来的数据是bytes格式,必须通过解码才能得到str格式内容
# decode默认参数是utf8
text = data.decode()
print(type(text))
print(text)
# 给对方返回的消息
rsp = "Ich hab keine Hunge"
# 发送的数据需要编码成bytes格式
# 默认是utf8
data = rsp.encode()
sock.sendto(data, addr)
if __name__ == '__main__':
import time
while 1:
try:
serverFunc()
except Exception as e:
print(e)
time.sleep(1)
TCP 编程
面向链接的传输,即每次传输之前需要先建立一个链接
客户端和服务端两个程序需要编写
Server 端的编写流程
建立 socket 负责具体通信,这个 socket 其实只负责接受对方的请求,真正通信的是链接后重新建立的 socket
绑定端口和地址
监听接入的访问 socket
接受访问的 socket,可以理解接受访问即建立了一个通讯的链接通路
接受对方的发送内容,利用接收到的 socket 接受内容
如果有必要,给对方发送反馈信息
关闭链接通路
Client 端的编写流程
建立通信 socket
链接对方,请求跟对方建立通路
发送内容到对方服务器
接受对方的反馈
关闭链接通路
案例 v04
import socket
def tcp_srv():
# 1. 建立socket负责具体通信,这个socket其实只负责接受对方的请求,真正通信的是链接后重新建立的socket
# 需要用到两个参数
# AF_INET: 含义同UDP一致
# SOCK_STREAM: 表明使用的是TCP进行通信
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 绑定端口和地址
# 此地址信息是一个元组类型内容,元组分两部分,第一部分为字符串,代表ip,第二部分为端口,是一个整数,推荐大于10000
addr = ("127.0.0.1", 8998)
sock.bind(addr)
# 3. 监听接入的访问socket
sock.listen()
while True:
# 4. 接受访问的socket,可以理解为接受访问即建立了一个通讯的链接通路
# accept返回的元组第一个元素赋值给skt,第二个赋值给addr
skt, addr = sock.accept()
# 5. 接受对方的发送内容,利用接受到的socket接受内容
# 500代表接受使用的buffersize
# msg = skt.receive(500)
msg = skt.recv(500)
# 接受到的是bytes格式内容
# 想得到str格式,需要进行解码
msg = msg.decode()
rst = "Receive msg: {0} from {1}".format(msg, addr)
print(rst)
# 6. 如果有必要,给对方发送反馈信息
skt.send(rst.encode())
# 7. 关闭链接通路
skt.close()
if __name__ == '__main__':
print("Starting tcp server........")
tcp_srv()
print("Ending tcp server..........")
- 案例v05
import socket
def tcp_clt():
# 1. 建立通信socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 链接对方,请求跟对方建立通路
addr = ("127.0.0.1", 8998)
sock.connect(addr)
# 3. 发送内容到对方服务器
msg = "I love you"
sock.send(msg.encode())
# 4. 接受对方的反馈
rst = sock.recv(500)
print(rst.decode())
# 5. 关闭链接通路
sock.close()
if __name__ == '__main__':
tcp_clt()
FTP 编程
FTP(FileTransferProtoacal)文件传输协议
用途:定制一些特殊的上传下载文件的服务
用户分类:登录 FTP 服务器必须有一个账号
Real 账户:注册账户
Guest 账户:可能临时对某一类人的行为进行授权
Anonymous 账户:匿名账户,允许任何人
FIP 工作流程
客户端链接远程主机上的 FTP 服务器
客户端输入用户名和密码(或者“anonymous”和电子邮件地址)
客户端和服务器进行各种文件传输和信息查询操作
客户端从远程 FTP 服务器退出,结束传输
FTP 文件表示
分三段表示 FTP 服务器上的文件
HOST:主机地址,类似于 ftp.mozilla.org, 以 ftp 开头
DIR:目录,表示文件所在本地的路径,例如 pub/android/focus/1.1-RC1
File:文件名称,例如 Klar-1.1-RC1.apk
如果想完整精确表示 ftp 上某一文件,需要上述三部分组合到一起
案例 v06
# 需要导入相应包,主要是ftplib
import ftplib # 关于FTP的操作都在这个包里边
import os
import socket
# 三部分精确表示在ftp服务器上的某一个文件
# 好多公开ftp服务器访问会出错或者没有反应
HOST = "ftp.acc.umu.se"
DIR = 'Public/EFLIB/'
FILE = 'README'
# 1. 客户端链接远程主机上的FTP服务器
try:
f = ftplib.FTP()
# 通过设置调试级别可以方便调试
f.set_debuglevel(2)
# 链接主机地址
f.connect(HOST)
except Exception as e:
print(e)
exit()
print("***Connected to host {0}".format(HOST))
# 2. 客户端输入用户名和密码(或者“anonymous”和电子邮件地址)
try:
# 登录如果没有输入用户信息,则默认使用匿名登录
f.login()
except Exception as e:
print(e)
exit()
print("***Logged in as 'anonymous'")
# 3. 客户端和服务器进行各种文件传输和信息查询操作
try:
# 更改当前目录到指定目录
f.cwd(DIR)
except Exception as e:
print(e)
exit()
print("*** Changed dir to {0}".format(DIR))
try:
# 从FTP服务器上下载文件
# 第一个参数是ftp命令
# 第二个参数是回调函数
# 此函数的意思是,执行RETR命令,下载文件到本地后,运行回调函数
f.retrbinary('RETR {0}'.format(FILE), open(FILE, 'wb').write)
except Exception as e:
print(e)
exit()
# 4. 客户端从远程FTP服务器退出,结束传输
f.quit()
Mail 编程
电子邮件的历史
起源
1969 Leonard K. 教授发给同事的 “LO”
1971 美国国防部自主的阿帕网(Arpanet)的通讯机制
通讯地址里用 @
1987 年中国的第一份电子邮件“Across the Great Wall we can reach every corner in the world”
管理程序
Euroda 使邮件普及
Netscape,outlook,forxmail 后来居上
Hotmail 使用浏览器发送邮件
参考资料
邮件工作流程
MUA(MailUserAgent) 邮件用户代理
MTA(MailTransferAgent) 邮件传输代理
MDA(MailDeliveryAgent) 邮件投递代理
laoshi@qq.com,老师,北京海淀
xuesheng@sina.com,学生,上海江岸区
流程
MUA->MTA,邮件已经在服务器上了
qq MTA->........-> sina MTA, 邮件在新浪的服务器上
sina MTA-> sina MDA, 此时邮件已经在你的邮箱里了
sina MDA -> MUA(Foxmail/Outlook), 邮件下载到本地电脑
编写程序
发送: MUA->MTA with SMTP: SimpleMailTransferProtocal, 包含 MTA->MTA
接受: MDA->MUA with POP3 and IMAP: PostOfficeProtocal v3 and InternetMessageAccessProtocal v4
准备工作
注册邮箱(以 qq 邮箱为例)
第三方邮箱需要特殊设置,以 qq 邮箱为例
进入设置中心
取得授权码
Python for mail
SMTP 协议负责发送邮件
使用 email 模块构建邮件
纯文本邮件
案例 v07
# 导入相应的包
import smtplib
from email.mime.text import MIMEText
# MIMEText三个主要参数
# 1. 邮件内容
# 2. MIME子类型,在此案例我们用plain表示text类型
# 3. 邮件编码格式
msg = MIMEText("Hello, i am xxxx", "plain", "utf-8")
# 发送email地址
from_addr = "1441865605@qq.com"
# 此处密码是经过申请设置后的授权码
from_pwd = "ajwvzqdlfigahiae" # 授权码
# 收件人信息
# 此时使用qq邮箱
to_addr = "1441865605@qq.com"
# 输入SMIP服务器地址
# 此处根据不同的邮件服务商有不同的值
# 现在基本任何一家邮件服务商,如果采用第三方收发邮件,都需要开启授权选项
# 腾讯qq邮箱所用的SMTP地址是 smtp.qq.com
smtp_srv = "smtp.qq.com"
try:
# 两个参数
# 第一个是服务器地址,但一定是bytes格式,所以需要编码
# 第二个参数是服务器的接受访问端口
srv = smtplib.SMTP_SSL(smtp_srv.encode(), 465) # SMTP 协议默认端口25
# 登录邮箱发送
srv.login(from_addr, from_pwd)
# 发送邮件
# 三个参数
# 1. 发送地址
# 2. 接受地址,必须是list格式
# 3. 发送内容,作为字符串发送
srv.sendmail(from_addr, [to_addr], msg.as_string())
srv.quit()
except Exception as e:
print(e)
- HTML格式邮件发送
- 准备HTML代码作为内容
- 把邮件的subtype设为html
- 发送
- 案例v08
from email.mime.text import MIMEText
mail_content = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1> 这是一封HTML格式邮件</h1>
</body>
</html>
"""
msg = MIMEText(mail_content, "html", "utf-8")
# 构建发送者地址和登录信息
from_addr = "1441865605@qq.com"
# 此处密码是经过申请设置后的授权码
from_pwd = "ajwvzqdlfigahiae" # 授权码
# 构建邮件接受者信息
to_addr = "971254246@qq.com"
smtp_srv = "smtp.qq.com"
try:
import smtplib
srv = smtplib.SMTP_SSL(smtp_srv.encode(), 465)
srv.login(from_addr, from_pwd)
srv.sendmail(from_addr, [to_addr], msg.as_string())
srv.quit()
except Exception as e:
print(e)
- 发送带附件的邮件
- 可以把邮件看作是一个文本邮件和一个附件的合体
- 一封邮件如果涉及多个部分,需要使用MIMEMultipart格式构建
- 添加一个MIMEText正文
- 添加一个MIMEBase或者MIMEText作为附件
- 案例v09
from email.mime.text import MIMEText # 构建附件使用
from email.mime.multipart import MIMEBase, MIMEMultipart # 构建基础邮件使用
mail_mul = MIMEMultipart()
# 构建邮件正文
mail_text = MIMEText("Hello, i am xxxx", "plain", "utf-8")
# 把构建好的邮件正文附加入邮件中
mail_mul.attach(mail_text)
# 构建附加
# 构建附件,需要从本地读入附件
# 打开一个本地文件
# 以rb格式打开
with open("02.html", "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-Disposition"] = "attachment; filename='02.html'"
# 添加到MIMEMultipart
mail_mul.attach(m)
# 发送email地址
from_addr = "1441865605@qq.com"
# 此处密码是经过申请设置后的授权码
from_pwd = "ajwvzqdlfigahiae" # 授权码
# 收件人信息
# 此时使用qq邮箱
to_addr = "1441865605@qq.com"
# 输入SMIP服务器地址
# 此处根据不同的邮件服务商有不同的值
# 现在基本任何一家邮件服务商,如果采用第三方收发邮件,都需要开启授权选项
# 腾讯qq邮箱所用的SMTP地址是 smtp.qq.com
smtp_srv = "smtp.qq.com"
try:
import smtplib
# 两个参数
# 第一个是服务器地址,但一定是bytes格式,所以需要编码
# 第二个参数是服务器的接受访问端口
srv = smtplib.SMTP_SSL(smtp_srv.encode(), 465) # SMTP 协议默认端口25
# 登录邮箱发送
srv.login(from_addr, from_pwd)
# 发送邮件
# 三个参数
# 1. 发送地址
# 2. 接受地址,必须是list格式
# 3. 发送内容,作为字符串发送
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
from email.mime.text import MIMEText
from email.header import Header
msg = MIMEText("Hello world", "plain", "utf-8")
# 用utf-8编码是因为很可能内容包含非英文字符
header_from = Header("从A发送出去的<A@qq.cn>", "utf-8")
msg['From'] = header_from
# 填写接受者信息
header_to = Header("去往B<B@sina.com>", "utf-8")
msg['To'] = header_to
header_sub = Header("这是主题", "utf-8")
msg['Subject'] = header_sub
# 构建发送者地址和登录信息
from_addr = "1441865605@qq.com"
from_pwd = "ajwvzqdlfigahiae"
# 构建邮件接受者信息
to_addr = "1441865605@qq.com"
smtp_srv = "smtp.qq.com"
try:
import smtplib
srv = smtplib.SMTP_SSL(smtp_srv.encode(), 465)
srv.login(from_addr, from_pwd)
srv.sendmail(from_addr, [to_addr], msg.as_string())
srv.quit()
except Exception as e:
print(e)
- 同时支持html和text格式
- 构建一个MIMEMultipart格式邮件
- MIMEMultipartd额subtype设置成alternative格式
- 添加HTML和Text邮件
- 案例v11
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 构建一个MIMEMultipart邮件
msg = MIMEMultipart("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("just text content", "plain", "utf-8")
msg.attach(msg_text)
# 发送email地址
from_addr = "1441865605@qq.com"
from_pwd = "ajwvzqdlfigahiae"
# 收件人信息:
# 此处使用我的qq邮箱
to_addr = "1441865605@qq.com"
# 输入SMTP服务器地址:
# 此地址根据每隔邮件服务商有不同的值,这个是发信邮件服务商的smtp地址
# 我用的是qq邮箱发送,此处应该填写腾讯qq邮箱的smtp值,即smtp.163.com,
# 需要开启授权码,
smtp_srv = "smtp.qq.com"
try:
import smtplib
# 加密传输
#server = smtplib.SMTP_SSL(smtp_srv.encode(), 465) # SMTP协议默认端口是25
# qq邮箱要求使用 TLS加密传输
server = smtplib.SMTP(smtp_srv.encode(), 25) # SMTP协议默认端口是25
server.starttls()
# 设置调试级别
# 通过设置调试等级,可以清楚的看到发送邮件的交互步骤
server.set_debuglevel(1)
# 登录发送邮箱
server.login(from_addr, from_pwd)
server.sendmail(from_addr, [to_addr], msg.as_string())
server.quit()
except Exception as e:
print(e)
- 使用smtplib模块发送邮件
- POP3协议负责接受邮件
- 本质上是MDA到MUA的一个过程
- 从 MDA 下载下来的是一个完整的邮件结构体,需要解析才能得到每个具体可读的内容
- 步骤:
1. 用poplib下载邮件结构体原始内容
1. 准备相应的内容(邮件地址,密码,POP3实例)
2. 身份认证
3. 一般会先得到邮箱内邮件的整体列表
4. 根据相应序号,得到某一封信的数据流
5. 利用解析函数进行解析出相应的邮件结构体
2. 用email解析邮件的具体内容
- 案例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 = "1441865605@qq.com"
# 邮箱的授权码
pwd = "ajwvzqdlfigahiae"
# pop3服务器地址
pop3_srv = "pop.qq.com" # 端口995
# 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返回所有邮件编号列表
# mails是所有邮件编号列表
rsp, mails, octets = srv.list()
# 可以查看返回的mails列表类似[b'1 82923', b'2 2184', ...]
print(mails)
# 获取最新一封邮件,注意,邮件索引号是从1开始, 最新代表索引号最高
index = len(mails)
# retr负责返回一个具体索引号的一封信的内容,此内容不具有可读性
# lines 存储邮件的最原始文本的每一行
rsp, lines, octets = srv.retr(index)
# 获得整个邮件的原始文本
msg_count = b'\r\n'.join(lines).decode("utf-8")
# 解析出邮件整个结构体
# 参数是解码后的邮件整体
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)
# 最终返回形如 "我的邮箱<xxx@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 = guessCharset(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 guessCharset(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:
# 如果包含chraset,则内容形如 charset=xxxx
charset = content_type[pos+8:].strip()
return charset
if __name__ == "__main__":
# 得到邮件的原始内容
msg = getMsg()
print(msg)
# 精确解析邮件内容
parseMsg(msg, 0)
版权声明: 本文为 InfoQ 作者【若尘】的原创文章。
原文链接:【http://xie.infoq.cn/article/494a3832bdfede598c9548eb5】。文章转载请联系作者。
若尘
还未添加个人签名 2021.01.11 加入
还未添加个人简介
评论