Python之并发+网络编程
off999 2024-12-13 15:36 38 浏览 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()相关推荐
- 不知道原机主id密码如何激活
-
答案:如果忘记ID账号和密码,可以尝试以下方法激活手机:1.使用备用邮箱或手机号码:如果您已将备用邮箱或手机号码与您的ID账号绑定,可以使用备用邮箱或手机号码进行身份验证以激活手机。2.联系客服:...
- win10安装需要输入产品密钥(win10安装程序要输入产品密匙)
-
可按照如下方式解决:1.右击桌面左下角的“Windows”按钮,然后点击“命令提示符”项。2.接下来再输入以下命令:slmgr/ipkW269N-WFGWX-YVC9B-4J6C9-T83GX按回...
- 手机秒变电脑摄像头(手机秒变电脑摄像头怎么设置)
-
可以的我用过,但是要你手机支持啊国产的山寨机很多都支持这个功能:支持这个功能的手机摄像头有两种工作状态:手机摄像状态和USB连接状态,在手机设置里把手机的摄像头改为USB连接状态,直接插到电脑上就可以...
- 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.情景游戏...
- office2010不激活可以用吗(window10中office不激活可以吗)
-
可以购买正版授权码激活或激活工具,不激活也可以一直用,但是每一次打开都会弹框。可以使用。因为Office2010不激活后,只会出现一个提醒框,并不影响软件的正常使用。但是未激活的Office2010不...
- 雨林木风在线重装系统(雨林木风系统安装教程win10)
-
一,一般雨林木风番茄花园之类的盗版系统重装系统后都是自动激活的,不需要再重新激活。二,如果偶尔系统提示没有激活的话,上系统之家等网站可以下载激活码,按提示激活即可。三,不建议安装雨林木风之类的盗版系统...
- 系统镜像文件放在哪里(系统镜像文件放在哪里好)
-
镜像文件路径在安装的U盘内有显示,如果没有显示,那是文件不对,或被解压了。镜像文件是一些压缩文件的统称。常见的有img格式的文件(例如,文本文件的格式是txt),它通常是用特定的软件,将本身自带启动文...
- mtu设置多少最好(mtu设置多少最好 4g)
-
路由器MTU的设置应根据网络情况决定,各种网络环境建议使用的MTU值如下:1.1500—以太网信息包最大值,也是默认值,是没有PPPoE和虚拟专用网络的网络连接的典型设置。是大部分路由器,网络适配器和...
- u盘最便宜多少钱一个(u盘最低价格)
-
一般情况下,一分钱,一分货;没有又便宜,货又好的事情。1、扩容盘。扩容盘是用PC技术,在量产时运用容量优先,输入了固定的容量,但它真实的容量只有标称容量的10倍左右。512M没人要的U盘扩容成4G,它...
- 小白三步装机教程(小白三步装机法)
-
下面给大家整理了一份小白装机的详细教程,有需要的朋友们快来看看吧!1、我们下载一个小白软件,然后选择了安装win7系统。2、在下载界面,下载速度取决于您的网络您只需要耐心等待即可。3、软件下载完成后会...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
python入门到脱坑 输入与输出—str()函数
-
宝塔面板如何添加免费waf防火墙?(宝塔面板开启https)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
失业程序员复习python笔记——条件与循环
-
系统u盘安装(win11系统u盘安装)
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
