写点什么

Python-Net 编程

用户头像
若尘
关注
发布于: 2021 年 04 月 16 日
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)
复制代码


发布于: 2021 年 04 月 16 日阅读数: 82
用户头像

若尘

关注

还未添加个人签名 2021.01.11 加入

还未添加个人简介

评论

发布
暂无评论
Python-Net编程