import socket import select class MakeRequest: '''用来将socket和url信息以及回调函数进行封装''' def __init__(self, sock, host, callback): self.sock = sock self.host = host self.callback = callback def fileno(self): return self.sock.fileno() # 可以放到select中 class AsyncRequest: '''根据发来的host进行访问''' def __init__(self): # 用来盛放socket对象 self.wlist = [] # 监听w self.rlist = [] # 监听r def add_socket(self, host, callback): '''根据host生成socket''' try: sock = socket.socket() sock.setblocking(0) # 设置为非阻塞 sock.connect((host, 80)) # 对主机进行连接,默认为80端口 except BlockingIOError as e: pass request = MakeRequest(sock, host, callback) # 将sock以及对应的封装在一起 self.wlist.append(request) self.rlist.append(request) # 检测是否连接上了 def run(self): '''运行socket''' while 1: r, w, e = select.select(self.rlist, self.wlist,self.rlist, 0.05) for w in self.wlist: '''对socket对象进行监听,如果w有动静,则说明连接上了''' print(w.host, '已经连接上') info = "GET / HTTP/1.0\r\nHost:%s\r\n\r\n" % (w.host) w.sock.send(bytes(info, encoding='utf-8'), ) self.wlist.remove(w) for r in self.rlist: # 用来接收数据 recv = bytes() while 1: try: chunk = r.sock.recv(8096) recv += chunk except Exception as e: break print(recv) r.callback(recv) r.sock.close() self.rlist.remove(r) if len(self.rlist) == 0: # 所有的socket都处理完成 break # 准备接口 def f1(data): print('f1') def f2(data): print('f2') def f3(data): print('f3') '''不同的url可以有不同回调函数''' url_list = [ {'host': 'www.baidu.com', 'callback': f1}, {'host': 'www.google.com', 'callback': f2}, {'host': 'www.cnblogs.com', 'callback': f3}, ] # 处理回调函数的时候,可以进行再次封装,将url和socket封装在一块 req = AsyncRequest() for url in url_list: # 先对urllist进行格式改变 req.add_socket(url['host'], url['callback']) req.run()