import asyncio, json, urllib.request, sys async def recv_one(reader): b1 = await reader.readexactly(2) fin_opcode = b1[0] masked_len = b1[1] length = masked_len & 0x7F if length == 126: ext = await reader.readexactly(2) length = int.from_bytes(ext, 'big') elif length == 127: ext = await reader.readexactly(8) length = int.from_bytes(ext, 'big') masked = (masked_len & 0x80) != 0 if masked: mask = await reader.readexactly(4) payload = await reader.readexactly(length) if length else b'' if masked: payload = bytes(b ^ mask[i % 4] for i, b in enumerate(payload)) return fin_opcode & 0x0F, payload async def send_text(writer, text): data = text.encode('utf-8') frame = bytearray() frame.append(0x81) n = len(data) mask = b'ABCD' if n < 126: frame.append(0x80 | n) elif n < (1<<16): frame.append(0x80 | 126) frame += n.to_bytes(2, 'big') else: frame.append(0x80 | 127) frame += n.to_bytes(8, 'big') frame += mask frame += bytes(b ^ mask[i % 4] for i, b in enumerate(data)) writer.write(frame) await writer.drain() async def main(): version = json.load(urllib.request.urlopen('http://127.0.0.1:9222/json/version')) ws = version['webSocketDebuggerUrl'] assert ws.startswith('ws://') hostportpath = ws[len('ws://'):] hostport, _, path = hostportpath.partition('/') host, port = hostport.split(':') port = int(port) path = '/' + path reader, writer = await asyncio.open_connection(host, port) key = 'dGhlIHNhbXBsZSBub25jZQ==' req = ( f'GET {path} HTTP/1.1\r\n' f'Host: {host}:{port}\r\n' 'Upgrade: websocket\r\n' 'Connection: Upgrade\r\n' f'Sec-WebSocket-Key: {key}\r\n' 'Sec-WebSocket-Version: 13\r\n\r\n' ) writer.write(req.encode()) await writer.drain() resp = await reader.readuntil(b'\r\n\r\n') print('HANDSHAKE_OK' if b'101' in resp else resp.decode(errors='ignore')) msgs = [ {"id":1,"method":"Browser.getVersion"}, {"id":2,"method":"Target.getTargets"}, {"id":3,"method":"Target.createTarget","params":{"url":"https://example.com"}}, ] for m in msgs: await send_text(writer, json.dumps(m)) for _ in range(10): opcode, payload = await recv_one(reader) if opcode == 1: txt = payload.decode('utf-8', errors='ignore') print(txt) elif opcode == 8: print('CLOSE') break writer.close() await writer.wait_closed() asyncio.run(main())