# -*- coding: utf-8 -*-
import socket, json, urllib.request, urllib.parse

HOST = 'localhost'
PORT = 9223

pages = json.loads(urllib.request.urlopen(f'http://{HOST}:{PORT}/json').read())
page_id = [p['id'] for p in pages if 'baijiahao.baidu.com' in p['url']][0]

ws_url = f'ws://{HOST}:{PORT}/devtools/page/{page_id}'
parsed = urllib.parse.urlparse(ws_url)
sock = socket.create_connection((parsed.hostname, parsed.port or 80), timeout=15)
key = 'dGhlIHNhbXBsZSBub25jZQ=='
handshake = f'GET {parsed.path} HTTP/1.1\r\nHost:{parsed.hostname}:{parsed.port}\r\nUpgrade:websocket\r\nConnection:Upgrade\r\nSec-WebSocket-Key:{key}\r\nSec-WebSocket-Version:13\r\n\r\n'
sock.send(handshake.encode())
resp = b''
while b'\r\n\r\n' not in resp:
    resp += sock.recv(4096)

def send(s, d):
    data = json.dumps(d).encode('utf-8')
    n = len(data)
    mask = b'\x01\x02\x03\x04'
    if n <= 125:
        hdr = bytes([0x81, n|0x80]) + mask
    elif n <= 65535:
        hdr = bytes([0x81, 0xFE]) + n.to_bytes(2, 'big') + mask
    s.send(hdr + bytes(data[i] ^ mask[i%4] for i in range(n)))

def recv(s):
    h = s.recv(2)
    n = h[1] & 0x7f
    if n == 126:
        n = int.from_bytes(s.recv(2), 'big')
    elif n == 127:
        n = int.from_bytes(s.recv(8), 'big')
    return s.recv(n).decode('utf-8')

# 获取页面完整 HTML 结构，查找编辑区域
expr = """
(function(){
    // 找整个编辑区域的父容器
    var editorArea = document.querySelector('[class*="editor"]') ||
                     document.querySelector('[class*="content"]');
    if(editorArea){
        return 'editor area class: ' + editorArea.className.substring(0,80);
    }
    return 'editor area not found';
})()
"""
send(sock, {'id':1,'method':'Runtime.evaluate','params':{'expression':expr}})
r = recv(sock)
print('编辑区域:', json.loads(r)['result']['result']['value'])

# 查看页面可见的 DOM 树结构
expr2 = """
(function(){
    // 从 body 开始，层层往下找编辑相关的 div
    var results = [];
    var divs = document.querySelectorAll('div');
    for(var d of divs){
        var cls = d.className ? d.className.toString() : '';
        if(cls.includes('editor') || cls.includes('content') || cls.includes('main') || cls.includes('body')){
            if(d.children.length > 0){
                results.push({
                    class: cls.substring(0,60),
                    childrenCount: d.children.length,
                    innerText: d.innerText ? d.innerText.substring(0,50) : ''
                });
            }
        }
    }
    return JSON.stringify(results.slice(0, 10));
})()
"""
send(sock, {'id':2,'method':'Runtime.evaluate','params':{'expression':expr2}})
r2 = recv(sock)
print('页面结构:', json.loads(r2)['result']['result']['value'])

# 获取当前输入框的光标位置和显示状态
expr3 = """
(function(){
    // 检查标题 input 和正文 textarea 的 computed style
    var input = document.querySelector('input[type="text"]');
    var ta = document.querySelector('textarea');
    return JSON.stringify({
        input: input ? {
            top: input.getBoundingClientRect().top,
            left: input.getBoundingClientRect().left,
            display: window.getComputedStyle(input).display,
            value: input.value.substring(0,30)
        } : null,
        textarea: ta ? {
            top: ta.getBoundingClientRect().top,
            left: ta.getBoundingClientRect().left,
            display: window.getComputedStyle(ta).display,
            valueLength: ta.value.length
        } : null
    });
})()
"""
send(sock, {'id':3,'method':'Runtime.evaluate','params':{'expression':expr3}})
r3 = recv(sock)
print('输入框位置和显示:', json.loads(r3)['result']['result']['value'])

sock.close()
