一、42_(1)greenlet
"""可以用greenlet替换(代)yield"""
from greenletimport greenlet
import time
"""
协程其实是一个假的多任务,真的多任务叫并行,
假的多任务叫并发。
导入的greenlet其实是一个类,可以实例化并调用。
实际开发中不使用; 用gevent
"""
def test1():
while True:
print ("---A--")
"""执行text2()函数"""
gr2.switch()
time.sleep(0.5)
def test2():
while True:
print ("---B--")
gr1.switch()
time.sleep(0.5)
gr1 = greenlet(test1)
gr2 = greenlet(test2)
"""执行函数text1()"""
gr1.switch()
二、42_使用gevent实现多任务
import gevent
"""推荐使用gevent实现多任务"""
import time
"""
gevent遇到【sleep:暂停(延时)】就切换到下一个命令执行
;没有就不切换
"""
from geventimport monkey
"""给程序打补丁"""
# 有耗时操作时需要
monkey.patch_all()
"""
将这个程序中用到的sleep:耗时操作的
代码gevent.sleep,换为time.sleep"""
def f1(n):
for iin range(n):
print(gevent.getcurrent(), i)
time.sleep(0.5)
# gevent.sleep(0.5)
"""循环遍历数字5,遍历一次延时0.5"""
def f2(n):
for iin range(n):
print(gevent.getcurrent(), i)
time.sleep(0.5)
# gevent.sleep(0.5)
def f3(n):
for iin range(n):
print(gevent.getcurrent(), i)
time.sleep(0.5)
# gevent.sleep(0.5)
"""
1、程序启动称为:进程(资源分配的单位);
2、执行代码的是:线程
3、单线程里执行多任务:协程
进程关闭、线程、协程随之挂掉
"""
print("---1---")
g1 = gevent.spawn(f1, 5)
"""参数f指定协程在哪执行, 需要传参就在后边直接写"""
print("---2---")
g2 = gevent.spawn(f2, 5)
print("---3---")
g3 = gevent.spawn(f3, 5)
print("---4---")
g1.join()
g2.join()
g3.join()
"""
recvfrom() #阻塞
# socket.connect()
# socket.accepet()
gevent.connect()
gevent.accepet()
"""
三、43_(1)图片下载器
"""gevent案例: 并发下载器"""
import urllib.request#爬虫经常用
# urllib.request.urlopen()
"""在urlopen()写上网址,可以和网址沟通"""
req = urllib.request.urlopen("http://www.baidu.con")
print(req.read())# read(): 读
四、43_(2)gevent_img_xzq
import urllib.request
"""gevent图片下载器"""
import gevent
from geventimport monkey
"""
爬多张图片可以封装成函数,
一个函数应该完成一个功能
"""
monkey.patch_all()
"""
将这个程序中用到的sleep:耗时操作的
代码gevent.sleep,换为time.sleep"""
def Pa1Ztu(img_name, img_url):
"""# img_name==(图片名. 格式)"""
req = urllib.request.urlopen(img_url)
img_content = req.read()#读图
with open(img_name, "wb")as f:
f.write(img_content)
""" !把图片保存到文件!
open:打开文件】, 第一个参数为图片名和
保存形式【wb:二进制的写入】拿到的图
片是二进制的,【write:写入"""
"""def miam():爬多张图的函数功能"""
def main():
gevent.joinall([
gevent.spawn(Pa1Ztu, "1.png", "http://p3.fx.kgimg.com/v2/fxuserlogo/00ea60c75e06bf74fce5507878e53a59.jpg_200x200.jpg"),
# gevent.spawn(PaYiZTu, "2.jpg", "")
])
if __name__ =="__main__":
main()
五、45_http协议1
一、浏览器向服务器发送的(请求)格式
1、GET: 浏览器向服务器索取数据(资源)
2、GET后面的是请求的网址名、协议版本
3、Host: 服务器的Ip地址、端口
4、keep-alive: 长链接
5、Accept: 服务器可以接收的数据格式
6、User-Agent: 浏览器的版本
7、Accept-Encoding: 能够接收的压缩格式
8、Accept-Language: 能接收的语言
二、服务器-->浏览器回送的数据格式如下:
1、Cache-Control:private 缓存是共享或私有的, 目前私有
2、Content-Encoding: 编码格式, 浏览器按此格式解压
3、Content-Type: 传输的是一个html的页面
4、Date: 服务器当前的时间
5、Server: 服务器, Bws是百度的服务器
6、Set-Cookie: 类似于xx服务器收集用户的信息数据
三、http(超文本传输)协议: 基于Tcp
六、47_简单web服务器实现
"""
http(超文本传输)协议: 基于Tcp
Tcp类似于2人通话可以接收到(稳定);
Cdp类似于广播, 有可能接收不到
"""
"""实现简单的http服务器"""
import socket
def service_client(new_socket):
"""为客户端返回数据"""
# 1、接收浏览器发送过来的请求, 即http请求
# -->例GET / HTTP/1.1 .....
requst = new_socket.recv(1024)
print(requst)
# 2、返回http格式的数据给浏览器
# 2.1 准备给浏览器发送的数据 :Header
response ="HTTP/1.1 200 OK\r\n"
response +="\r\n"
"""【\r\n: 换行(兼容所有的浏览器)】"""
# 2.2 准备给浏览器发送的数据 :Body
response +="
hehehe
"
new_socket.send(response.encode("utf-8"))
"""【send: 发送【encode: 编码】"""
# 关闭套接字
new_socket.close()
def main():
"""用来整体控制"""
# 1、创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
"""选择让服务端先关闭"""
# 2、绑定; 参数("任意服务端ip", 端口)
tcp_server_socket.bind(("", 7890))
# 3、变为监听的套接字; 【listen:最大链接数】
tcp_server_socket.listen(128)
while True:
# 4、等待新客户端的连接; 变量[新客户端的套接字, 客户端的IP、端口]
new_socket, client_addr = tcp_server_socket.accept()
# 5、为这个客户端服务
service_client(new_socket)
# 6、关闭监听套接字
tcp_server_socket.close(new_socket)
if __name__ =='__main__':
main()