监测点
看到阿龙的博客 中有selenium 中打开带有 dev-tools 的页面会跳转到新的页面
原文在这里
项目代码
这段代码是 dev-tools 中 检测性能的代码. 两次检查 tablePrintTime > logPrintTime * 20 的时候触发条件.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body>
<div id="tablePrintTimeDisplay">Table Print Time: --</div> <div id="logPrintTimeDisplay">Log Print Time: --</div>
<script>
function now() { return new Date().getTime(); }
function calculateTime(func) { const start = now(); func(); return now() - start; }
function createLargeObject() { const largeObject = {}; for (let i = 0; i < 500; i++) { largeObject[`${i}`] = `${i}`; } return largeObject; }
function createLargeObjectArray() { const largeObject = createLargeObject(); const largeObjectArray = [];
for (let i = 0; i < 50; i++) { largeObjectArray.push(largeObject); }
return largeObjectArray; }
const largeObjectArray = createLargeObjectArray();
const tablePrintTime = calculateTime(() => { console.table(largeObjectArray); }); const logPrintTime = calculateTime(() => { console.log(largeObjectArray); });
console.log(tablePrintTime); console.log(logPrintTime);
document.getElementById('tablePrintTimeDisplay').textContent = 'Table Print Time: ' + tablePrintTime + ' ms'; document.getElementById('logPrintTimeDisplay').textContent = 'Log Print Time: ' + logPrintTime + ' ms';
</script> </body> </html>
|
保存文件到test.html 使用file://test.html 打开之后页面显示
1 2
| Table Print Time: 0 ms Log Print Time: 1 ms
|
使用selenium 打开检测网页
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import time from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options
def connect_remote_debugging(): print("开始准备连接远程调试浏览器...") chrome_options = Options() chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
try: driver_path = "/usr/local/chromedriver" service = Service(executable_path=driver_path) print(f"正在通过驱动 {driver_path} 连接到 127.0.0.1:9222...") driver = webdriver.Chrome(service=service, options=chrome_options)
url = "file:///root/project/weview2/test.html" print(f"正在接管并打开页面: {url}") driver.get(url) print(f"连接成功!当前页面标题: {driver.title}")
print("开始睡眠 100 秒,请观察浏览器...")
except Exception as e: print(f"发生错误: {e}") import traceback traceback.print_exc() finally: print("执行完成")
if __name__ == "__main__": connect_remote_debugging()
|
1 2
| Table Print Time: 112 ms Log Print Time: 1 ms
|
使用Playwright 打开页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| import sys import asyncio from playwright.async_api import async_playwright
def log(msg): print(msg, flush=True)
async def main(): log("正在连接到远程调试端口 9222...") async with async_playwright() as p: try: log("尝试连接 CDP...") browser = await p.chromium.connect_over_cdp("http://127.0.0.1:9222") log(f"连接成功!浏览器版本: {browser.version}") default_context = browser.contexts[0] log(f"获取到上下文,页面数量: {len(default_context.pages)}") if default_context.pages: page = default_context.pages[0] log("使用现有页面") else: page = await default_context.new_page() log("创建新页面") url = "file:///root/project/weview2/test.html" log(f"正在打开页面: {url}") await page.goto(url) log(f"页面已打开,标题: {await page.title()}") await page.wait_for_load_state("networkidle") log("页面加载完成") table_time = await page.text_content("#tablePrintTimeDisplay") log_time = await page.text_content("#logPrintTimeDisplay") log(f"页面显示: {table_time}") log(f"页面显示: {log_time}") log("开始睡眠 100 秒...") await asyncio.sleep(100) log("睡眠结束") except Exception as e: log(f"发生错误: {e}") import traceback traceback.print_exc()
if __name__ == "__main__": log("脚本启动...") asyncio.run(main()) log("脚本结束")
|
1 2
| 页面显示: Table Print Time: 93 ms 页面显示: Log Print Time: 1 ms
|
hook 脚本
1 2 3 4 5 6 7 8 9 10 11 12
| driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { "source": """ (function() { // 彻底阻断 console.table 的序列化逻辑 Object.defineProperty(console, 'table', { get: () => function() { return; }, set: () => {} }); console.log('Performance optimization active.'); })(); """ })
|
结论
问了AI,意思是没有办法通过工具降低console.table 的延时,这是blink 内部序列化的固定耗时,去掉延时,只能hook console.table 的方式.
你需要理解这 90ms 的本质:它是“数据搬运费”。
- 没有调试器时:浏览器执行
console.table(data),发现没人看,直接在内存里丢弃,耗时 1ms。
- 有 Selenium 时:浏览器执行
console.table(data),发现有一个叫“Selenium”的家伙正连着 CDP 端口。它不得不把这几千行数据序列化成 JSON 字符串,准备通过 WebSocket 发送。这个过程发生在浏览器内核深处,耗时 90ms。
只要你不 Hook console.table,只要 Selenium 还连着,这 90ms 的“搬运费”就必须交。 因为浏览器无法预知你是否会调用 driver.get_log('browser')。