百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

Python之并发+网络编程

off999 2024-12-13 15:36 39 浏览 0 评论

第一节:网络模块概述与urllib.parse模块讲解

  • 网络分层及协议(TCP/IP)
  • Python的网络模块
    • socket:基于传输层TCP、UDP协议进行网络编程的模块
    • email:Email和MIME消息处理模块
    • smtplib:支持SMTP协议(发送邮件)的客户端模块
    • poplib:支持POP3协议的客户端模块
    • urllib及其子模块:支持URL处理的模块
      • urllib.parse:用于解析URL
      • 使用urlparse()函数来解析字符串
      • 使用urlunparse()函数则可以把一个parseresult对象或元组恢复成URL字符串


import urllib.parse

# urlparse()用于解析URL字符串,返回值为ParseResult(tuple的子类)
# urlunparse()将URL各部分(ParseResult或tuple)恢复成URL字符串

s = 'http://www.crazyit.org:80/index.html;abc?name=yeeku#myfrag'
# 解析url字符串
r = urllib.parse.urlparse(s)
# ParseResult对象
print(r)
# ParseResult是tuple的子类
print('协议', r.scheme, r[0])
print('位置', r.netloc, r[1])
print('资源路径', r.path, r[2])
print('参数', r.params, r[3])
print('字符串查询', r.query, r[4])
print('fragment', r.fragment, r[5])

# 元组
tu = ('https', 'www.python.org:80', '/index.html', 'wawa', 'name=yoku', 'title')
# 恢复查询字符串
print(urllib.parse.urlunparse(tu))
    • 处理查询字符串
      • parse_qs()和parse_qsl()(这个l代表list)两个函数都用于解析查询字符串,只不过返回值不同而已,parse_qsl()返回的是list
      • urlencode()则是他们的逆函数
import urllib.parse

# parse_qs()和parse_qsl()用于解析查询字符串,得到字典或者列表
# urlencode()将列表或者字典恢复成查询字符串

#查询字符串格式:key=value,多个key=value之间用&隔开
qs = 'name=python&name=crazyit&age=27&height=182'
# 返回字典
print(urllib.parse.parse_qs(qs))

# 返回列表
print(urllib.parse.parse_qsl(qs))

# 已有列表
lt = [('name', 'python'), ('name', 'crazyit'), ('age', '23')]
# 将列表恢复成查询字符串
print(urllib.parse.urlencode(lt))

# 已有字典
query_dict = {'name': 'python', 'age': '23', 'height': '183'}
# 将字典恢复成查询字符串
print(urllib.parse.urlencode(query_dict))

第二节:案例实操-使用urllib模块读取网络资源及提交请求

  • urllib.request.urlopen(url, data=None)方法,用于打开url指定的资源,并从中读取数据
import urllib.request
# urlopen(url, data=None) 打开URL对应的资源

# 打开网络资源之后,该资源就像一个文件,可以按照文件的方式进行处理
with urllib.request.urlopen('https://www.crazyit.org/index.php') as f:
    print(f.read(510).decode('UTF-8'))
  • 使用urlopen()函数时可以通过data参数向被请求的url发送数据
  • 发送GET请求参数时,只要将请求参数追加到URL后面即可
import urllib.request

# 用字典代表请求参数
params = {'name': 'python', 'passwd': '665815'}

# GET请求参数,只需添加到URL之后即可(使用自己本身的IP地址及路径下的文件测试)
with urllib.request.urlopen('https://192.168.1.17:8888/test/get.jsp?%s' % urllib.parse.urlencode(params)) as f:
    print(f.read().decode('UTF-8'))
    
# post请求参数,用data参数来指定
with urllib.request.urlopen('https://192.168.1.17:8888/test/post.jsp?%s' data = urllib.parse.urlencode(params).encode('utf-8')) as f:
    print(f.read().decode('UTF-8'))
  • 如果发送PUT、PATCH、DELETE等请求,此时需要用urllib.request.Request来构建请求参数
  • 构建Request对象时,可以用method参数指定请求方法
import urllib.request

# 定义需要put的请求参数
params = 'put数据'.encode('utf-8')
# 如果发送PUT、PATCH、DELETE等请求,此时需要用urllib.request.Request来构建请求参数
req = urllib.request.Request(url='https://192.168.1.17:8888/test/put', data=params, method='PUT')
# 有了Request对象之后,用urlopen打开对象即可
with urllib.request.urlopen(req) as f:
    print(f.read().decode('UTF-8'))
  • 访问被保护的资源,需要先登录再访问
import urllib.request
import http.cookiejar
# 如果你要能保持客户端多次请求的状态,那么必须借助于cookie


# 创建cookiejar对象
cookie_jar = http.cookiejar.MozillaCookieJar('a.txt')
# 创建一个cookie处理器
cookie_proc = urllib.request.HTTPCookieProcessor(cookie_jar)
# 创建OPenerDirector对象,当程序使用OPenerDirector对象来发送多次请求时,
# 他们使用相同的cookie,因此服务端就可以维持多次访问的状态
opener = urllib.request.build_opener(cookie_proc)

# 用字典代表请求参数
params = {'name': 'crazyit.org', 'pass': 'leegang'}


with opener.open('https://192.168.1.17:8888/test/login.jsp'\
    , data=urllib.parse.urlencode(params).encode('utf-8')) as f:
    print(f.read().decode('UTF-8'))
    
# 尝试访问被保护的资源(必须先登录才能访问的字眼)
with opener.open('https://192.168.1.17:8888/test/secret.jsp') as f:
    print(f.read().decode('UTF-8'))


第三节:TCP协议概述及python的TCP支持与创建TCP服务器

  • tcp/ip协议相关的网络知识就不在这里赘述了
# server端
import socket,threading
'''
参数一:指定网络类型 AF_INET:IPV4网络, AF_INET6:IPV6网络 AF_UNIX:UNIX网络
参数二:指定socket类型 SOCK_STREAM:TCP SOCK_DGRAM:UDP
'''

'''
创建套接字之后,需要绑定到指定的IP和端口,监听来自客户端的链接,接受来自客户端的链接
创-》绑-》监-》接-》关
'''
# 定义一个列表
client_list = []
def server_target(server_socket):
    # 一旦建立链接之后,server与client虚拟链路建立成功    
    while True:
        content = client_socket.recv(2048).decode('UTF-8')
        if content is not None:
            # 读取到数据之后,将数据打印出来
            print(content)
            # 将数据再送回到每个客户端
            for cl in client_list:
                cl.send(content.encode('utf-8'))
            
# 步骤一:创建套接字
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)

# 步骤二:绑定套接字
s.bind(('10.10.24.15', 23))

# 步骤三:监听套接字
s.listen()
# 步骤四:链接套接字
while True:
    # 接收来自客户端的链接
    # 该方法返回两个参数,c代表与客户端socket对应的、通信的socket
    # addr代表客户端的地址
    c, addr = s.accept()
    print(addr)
    # 将所有客户端对应的socket保存到列表中
    client_list.append(c)
    # 为客户端对应的socket启动对应的线程
    threading.Thread(target=server_target, argc=(c,)).start()
    
    # 步骤五:关闭套接字
    c.close()

第四节:使用socket通信并加入多线程

  • 通过threading.Thread创建线程
  • 服务端为每个客户端启动一条线程,保证各客户端互不干扰
  • 客户端为网络IO启动一条线程,为用户交互启动一条线程
# client端
import socket,threading

def read_server(client_socket):
    # 一旦建立链接之后,server与client虚拟链路建立成功    
    while True:
        content = client_socket.recv(2048).decode('UTF-8')
        if content is not None:
            print(content)
        
# 步骤一:创建套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)

# 步骤二:connect链接服务端
client_socket.connect(('10.10.24.15', 23))

# 将read_server函数以多线程的方式启动,这样该函数(包含死循环)能与下面的死循环并发执行
threading.Thread(target=read_server, args=(client_socket,)).start()

while True:
    # 获取用户输入
    line = input('')
    if line is None or line == 'exit':
        break
    # 将用户输入的内容写入网络
    client_socket.send(line.encode('UTF-8'))
    
# 关闭套接字
client_socket.close()

第五节:案例实操-使用smtplib模块发送邮件

  • 使用smtplib库来发送邮件大致只要三步:
    • 1. 链接smtp服务器,并使用用户名密码登录服务器
    • 2. 创建EmailMessage对象,该对象代表了邮件本身
    • 3. 调用代表与SMTP服务器链接对象的sendmail()方法发送邮件
  • 添加附件
    • 调用EmailMessage的add_attachment()方法,支持的参数如下
      • maintype:指定附件的主题
      • subtype:指定附件的子类型
      • filename:指定该附件的文件名
      • cid=img:指定该附件的资源ID
import  smtplib
import email.message
import email.utils
'''
# smtplib.SMTP 代表普通的SMTP连接
# smtplib.SMTP_SSL() 代表基于SSL的SMTP连接
# coon = smtplib.SMTP('smtp.qq.com', 21)
# coon = smtplib.SMTP_SSL('smtp.qq.com', 465)
'''
# 生成一个cid
first_id = email.utils.make_msgid()

fromaddr = 'kongyeeku@qq.com'
# qq邮箱要开启安全码
password = 'diwpwjfoasosng'

# 创建SMTP连接
coon = smtplib.SMTP_SSL('smtp.qq.com', 465)
coon.set_debuglevel(1)

# 步骤一:登录邮件服务器
conn.login(fromaddr, password)

# 步骤二:创建EmailMessage对象
msg = email.message.EmailMessage()
# 设置邮件内容(普通邮件)
# msg.set_content('您好,Python邮件')

# 设置邮件内容(HTML邮件)
msg.set_content('<h2>HTML邮件</h2>' 
+ '<div style="border:lps:solod red">html邮件内容</div>', 'html', 'UTF-8')
# 用于设置邮件的主题、发件人和收件人
msg['subject']='HTML邮件'
msg['from']='xxx<%s>' % fromaddr
msg['to']='xxx<%s>' % 'aaaa@qq.com'

# 添加附件
# 附件指定了cid之后,邮件正文可通过cid来引用该图片
with open('e:/logo.jpg', 'rb') as f:
    msg.add_attachment(f.read(), maintype='image', 
    subtype='jpeg', filename='test.jpg', cid=first_id)

# 步骤三:sendmail方法发送邮件
conn.sendmail(fromaddr,['aaaa@qq.com', 'bbbb@qq.com'],msg.as_string())

# 退出文件
conn.quit()

第六节:使用poplib模块收取文件

  • 使用poplib模块提供的poplib.POP3和poplib.POP_SSL两个类,分别用于连接普通的pop服务器和基于SSL的pop服务器,现在都使用poplib.POP_SSL类
  • pop3的命令和响应都是基于ASCII文本的,并以CR和LF(/r/n)作为行结束符
  • 响应包括一个表示返回状态的符号(+/-),和描述信息
  • 请求和响应的标准格式如下:
    • 请求标准格式:命令[参数]CRLF
    • 响应标准格式:+OK/[-ERR] description CRLF
  • 常见命令
    • stat:统计邮件服务器状态,包括邮件数和总大小
    • list[mas_no]:列出全部邮件或者指定邮件,返回邮件编号和对应的大小
    • retr msg_no:获取指定邮件的内容(根据邮件序号来获取,序号从1开始)
import  poplib
import email.parser, email.policy

# 创建与邮件服务器的链接
# conn = poplib.POP3('pop.qq.com', 110) 传统的不安全的

# 基于SSL
conn = poplib.POP3_SSL('pop.qq.com', 995) 
coon.set_debuglevel(1)

print(conn.getwelcome().decode('utf-8'))


conn.user('kongyeeku@qq.com')# 相当于使用user命令
conn.pass_('diwpwjfoasosng')# 相当于使用pass命令,qq安全码

# 统计邮件信息,相当于stat命令
num, totalsize = conn.stat()
print('邮件数', num)
print('总大小', totalsize)

# 获取邮件列表,相当于list命令
resp, maillist,r = conn.list()
print('响应:', resp)
print('邮件列表:', maillist)

# 获取最后一封邮件
resp, maildata, r = conn.retr(len(maillist))
print('响应:', resp)
print('邮件数据:', maildata)
data = b'\r\n'.join(maildata)

# 将邮件数据恢复成EmailMessage对象
msg = email.parser.BytesParser(policy=email.policy.default).parsebytes(data)
print(type(msg))

print('发件人', msg['from'])
print('收件人', msg['to'])
print('主题', msg['subject'])
print('第一个发件人用户名', msg['from'].address[0].username)
print('第一个收件人用户名', msg['to'].address[0].username)


# 遍历邮件内容,邮件每个部分都是一个part
for part in msg.walk():
    # multipart代表邮件内容的容器,无需处理,继续读取它包含的part即可
    if part.get_content_tpye() == 'multipart':
        continue
    # 代表邮件的正文
    elif part.get_content_tpye() == 'test':
        print(part.get_comtent())
    # 剩下的就是邮件的附件
    else:
        filename = part.get_filename # 得到附件的文件名
        # 将附件下载(写入)本地磁盘文件
        with open(filename, 'wb') as f:
            f.write(part.get_payload(decode=True))
# 退出服务器,相当于quit命令
conn.quit()

相关推荐

联通路由器怎么改wifi密码(联通路由器怎么改wifi密码和名称)
  • 联通路由器怎么改wifi密码(联通路由器怎么改wifi密码和名称)
  • 联通路由器怎么改wifi密码(联通路由器怎么改wifi密码和名称)
  • 联通路由器怎么改wifi密码(联通路由器怎么改wifi密码和名称)
  • 联通路由器怎么改wifi密码(联通路由器怎么改wifi密码和名称)
怎么查电脑型号配置(电脑怎么看型号配置)
  • 怎么查电脑型号配置(电脑怎么看型号配置)
  • 怎么查电脑型号配置(电脑怎么看型号配置)
  • 怎么查电脑型号配置(电脑怎么看型号配置)
  • 怎么查电脑型号配置(电脑怎么看型号配置)
电脑如何修改默认浏览器(电脑上怎样修改默认浏览器)

1、按下“windows+i”快捷键打开Windows设置,在设置界面选择系统。2、在系统里左边点击默认程序一项,右边会出现新的选项来。3、右边滚动鼠标滑轮下拉,点击web默认程序,点击选择想要默认打...

如何下载youtube视频(如何下载youtube视频2160p)

这个可以在应用宝中下载,就是在手机上下载一个应用宝,然后在搜索栏里输入软件名字,点击搜索,根据提示下载就可以了。将视频下载到电脑上有几种途径,如果是网络上的,可以下载的视频会设置有下载标记或按钮,点...

深度国际2025最新一期视频(今日关注最新一期的)

1、就算不快乐也不要皱眉,因为你永远不知道谁会爱上你的笑容。2、踏入社会的时候,不要什么话都跟别人讲,你说的是心里话,别人听的是笑话。3、该扔的就扔,该放弃就放弃,从今天起,余生做个俗人,以自己最好的...

华为最新系统版本(华为最新系统版本微信)

鸿蒙3.0。鸿蒙最新版本是3.0系统,相比2.0有着全面提升。尤其是在交互设计,多设备互联互通,流畅度性能,安全属性,用户关怀等方面升级幅度最大,而且升级并非是简单的更新换代,修复了不少鸿蒙2.0版本...

不知道原机主id密码如何激活

答案:如果忘记ID账号和密码,可以尝试以下方法激活手机:1.使用备用邮箱或手机号码:如果您已将备用邮箱或手机号码与您的ID账号绑定,可以使用备用邮箱或手机号码进行身份验证以激活手机。2.联系客服:...

win10安装需要输入产品密钥(win10安装程序要输入产品密匙)

可按照如下方式解决:1.右击桌面左下角的“Windows”按钮,然后点击“命令提示符”项。2.接下来再输入以下命令:slmgr/ipkW269N-WFGWX-YVC9B-4J6C9-T83GX按回...

手机秒变电脑摄像头(手机秒变电脑摄像头怎么设置)

可以的我用过,但是要你手机支持啊国产的山寨机很多都支持这个功能:支持这个功能的手机摄像头有两种工作状态:手机摄像状态和USB连接状态,在手机设置里把手机的摄像头改为USB连接状态,直接插到电脑上就可以...

苹果ipad充不上电是什么原因
  • 苹果ipad充不上电是什么原因
  • 苹果ipad充不上电是什么原因
  • 苹果ipad充不上电是什么原因
  • 苹果ipad充不上电是什么原因
bios没有advanced选项(bios没有advanced选项卡)

华硕主板可开机后点击ESC键或F12键选择AdvancedBIOSFeatures项:你说的只很少几项可以修改,可能是分别设置了CMOS密码和开机密码。而你进入COMS时输的的开机密码!要输入C...

路由器选购技巧(路由器选购技巧大全)

第一,WI-FI协议;我们在购买路由器的时候需要仔细注意分辨WI-FI协议是厂家的噱头还是真正实用的,对上网体验有帮助的功能。目前的Wi-Fi协议已经发展到第6代,既厂商宣传的Wi-Fi...

联想电脑摄像头驱动怎么安装
  • 联想电脑摄像头驱动怎么安装
  • 联想电脑摄像头驱动怎么安装
  • 联想电脑摄像头驱动怎么安装
  • 联想电脑摄像头驱动怎么安装
win7电脑没有声音怎么解决(win7电脑为什么没声音)

1.在我们的win7系统中,突然间没有声音,此时用鼠标右键点击电脑左边的开始菜单,选择“管理”按钮。2.在此页点击系统工具下面的设备管理器,然后展开声音、视频和游戏控制器此选项。3、在该选项当中,...

playstore(playstore app install english)

原文:PlayStore翻译:谷歌的电子市场,或者是指一些虚拟的电子商城。例句:Playstore,restaurant,oricecreamstandtogether.情景游戏...

取消回复欢迎 发表评论: