5.6 KiB
5.6 KiB
| name | description | tags | |||||
|---|---|---|---|---|---|---|---|
| dynamic-page-extract | 提取SPA/动态渲染页面的完整内容,解决browser_snapshot无法获取JS渲染后DOM的问题 |
|
Dynamic Page Content Extraction
browser_snapshot 获取的是 accessibility tree,JS 动态渲染的内容经常缺失。用 browser_console + CDP 绕过。
核心方法:browser_console(expression=...)
# 获取完整页面文本
result = browser_console(expression="document.body ? document.body.innerText : 'no body'")
# 获取特定元素内容
result = browser_console(expression="document.querySelector('.content')?.innerText")
# 获取所有可见文本(排除script/style)
result = browser_console(expression="""
Array.from(document.querySelectorAll('p, h1, h2, h3, h4, h5, h6, li, td, th, span, div'))
.filter(el => el.offsetParent !== null && el.innerText.trim())
.map(el => el.innerText.trim())
.join('\\n')
""")
# 获取表格数据
result = browser_console(expression="""
JSON.stringify(
Array.from(document.querySelectorAll('table tr')).map(row =>
Array.from(row.querySelectorAll('td, th')).map(cell => cell.innerText.trim())
)
)
""")
等待动态内容
# 等待特定内容出现
for _ in range(20): # 10秒超时
result = browser_console(expression="""
(function() {
const el = document.querySelector('.result-content');
return el && el.innerText.trim() ? el.innerText.trim() : 'WAITING';
})()
""")
if 'WAITING' not in str(result):
break
terminal("sleep 0.5")
CDP Runtime.evaluate 获取完整 DOM
# 获取完整innerHTML(需设置 allow_unsafe_evaluate: true 或通过 browser_console)
result = browser_console(expression="document.documentElement.outerHTML.substring(0, 50000)")
# 获取body内HTML
result = browser_console(expression="document.body.innerHTML.substring(0, 30000)")
绕过限制
browser_console(expression=...) 在 sandbox 中可能被拦截 fetch/network。使用纯 DOM 读取:
# ✅ 允许 - DOM读取
browser_console(expression="document.querySelector('.price').innerText")
# ❌ 可能被拦截 - 网络请求
browser_console(expression="fetch('/api/data')...")
如需网络请求,用 terminal + curl 替代。
交互操作:查找并点击隐藏/不可见按钮
browser_snapshot 只能看到 accessibility tree 中的元素,bricks 表单的 Submit 按钮经常不在 snapshot ref 中。用 browser_console IIFE 查找并点击:
# 查找 Submit 按钮(bricks 登录表单常见模式)
browser_console(expression="""
(function(){
var all = document.querySelectorAll('*');
for(var i=0;i<all.length;i++){
if(all[i].textContent.trim()==='Submit'){
return all[i].tagName+'.'+all[i].className+' id:'+all[i].id
}
}
return 'not found'
})()
""")
# 点击找到的按钮(browser_console 必须用 IIFE 包裹)
browser_console(expression="(function(){document.getElementById('submit').click(); return 'clicked'})()")
# 匹配文本内容点击工具栏按钮
browser_console(expression="""
(function(){
var items = document.querySelectorAll('[class*=toolbar] > div, [class*=htoolbar] > div');
for(var i=0;i<items.length;i++){
if(items[i].textContent.includes('产品分销')){
items[i].click(); return 'clicked:'+items[i].textContent.trim().substring(0,30)
}
}
return 'not found'
})()
""")
# bricks Tabular 行选择(DOM click 不触发 bricks 内部 selection)
# 解决方法:直接导航到目标 CRUD 页面 + URL filter 参数
browser_navigate('/module/crud_list?filter_field=value')
注意:多行 JS 表达式必须用 IIFE (function(){...})() 包裹,顶层 return 无效。
登录 bricks 应用
bricks 登录表单的 Submit 按钮不可见(不在 snapshot ref 中),用以下流程:
browser_navigate('https://app.com/rbac/user/login.ui')
browser_type(ref='@e10', text='username')
browser_type(ref='@e11', text='password')
# 找到并点击隐藏的 Submit 按钮
browser_console(expression="(function(){document.getElementById('submit').click(); return 'done'})()")
terminal("sleep 3")
# 验证登录成功
browser_navigate('https://app.com/protected_page')
content = browser_console(expression="document.body.innerText.substring(0,200)")
常见模式
SPA 路由页面内容
browser_navigate('https://spa-app.com/dashboard')
# 等2秒让JS渲染
terminal("sleep 2")
content = browser_console(expression="document.querySelector('#app')?.innerText || document.body.innerText")
登录后页面
browser_navigate('https://app.com/login')
browser_type(ref='@e10', text='user')
browser_type(ref='@e11', text='password')
browser_click(ref='@e4')
terminal("sleep 3") # 等登录完成
content = browser_console(expression="document.querySelector('.dashboard')?.innerText")
无限滚动页面
for i in range(5):
browser_scroll(direction='down')
terminal("sleep 1") # 等新内容加载
content = browser_console(expression="document.body.innerText")
与 browser_snapshot 对比
| 方法 | 获取内容 | 适用场景 |
|---|---|---|
| browser_snapshot | accessibility tree | 静态页面、表单交互 |
| browser_console(expression) | 真实DOM | SPA、动态渲染、数据提取 |
规则: 如果 browser_snapshot 返回空或不完整,立即切换到 browser_console(expression="document.body.innerText")。