抓取动态网页(JS 渲染内容)的 Skill。基于 Playwright + 系统 Chrome,支持三种模式。
playwright 包)/usr/bin/google-chrome安装方式:
bash
cd /home/axelhu/.openclaw/workspace
npm install playwright
创建 Chrome wrapper,让所有 google-chrome 命令默认开启调试端口:
bash
mkdir -p ~/bin
cat > ~/bin/google-chrome << 'EOF'
#!/bin/bash
exec /usr/bin/google-chrome --remote-debugging-port=9222 "$@"
EOF
chmod +x ~/bin/google-chrome
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc
export PATH="$HOME/bin:$PATH"
bash
# 必须加 DISPLAY=:0,否则 exec 会话中 Chrome 无法找到显示器
DISPLAY=:0 google-chrome \
--remote-debugging-port=9222 \
--user-data-dir=$HOME/.config/google-chrome/Default \
--new-window \
--no-sandbox \
> /tmp/chrome-debug.log 2>&1 &
# 验证启动成功
sleep 3 && curl -s http://localhost:9222/json/version | head -c 50
注意:
--user-data-dir=$HOME/.config/google-chrome/Default使用你的默认 Chrome profile,登录状态会被复用。如果不想影响日常 Chrome,另用独立目录。
bash
bash /home/axelhu/.openclaw/skills/axelhu-playwright-scrape/scripts/start-chrome-debug.sh
text
node skills/axelhu-playwright-scrape/scripts/playwright-scrape.js <URL> [mode]
mode: gui(默认)、 headless、 stealth连接已启动的 Chrome(gui 模式):
javascript
const { chromium } = require('/home/axelhu/.openclaw/workspace/node_modules/playwright');
const browser = await chromium.connectOverCDP('http://localhost:9222');
const page = (await browser.contexts())[0].pages()[0]; // 复用已有标签页
新建标签页(新 context):
javascript
const ctx = await browser.newContext();
const page = await ctx.newPage();
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 15000 });
await page.waitForTimeout(4000); // 等待 JS 渲染
模式适用场景特点gui有反爬的网站(知乎/小红书/B站等)复用用户 Chrome,指纹真实,可绕过检测headless普通动态网站后台运行,不需要显示器stealth中等反爬目标反爬启动参数,适合不需要真实浏览器的场景
gui 模式复用了用户本地的 Chrome profile,cookie/登录态直接沿用,无需额外认证。
平台登录后能抓小红书帖子全文、搜索结果、推荐流知乎话题页、热榜、回答全文B站排行榜、视频信息、关注列表豆瓣小组讨论、精选内容
javascript
// 获取当前登录用户的 SESSDATA cookie
const cookies = await ctx.cookies(['https://bilibili.com']);
const sessdata = cookies.find(c => c.name === 'SESSDATA')?.value;
// 调用 B站 API
const resp = await fetch('https://api.bilibili.com/x/relation/followings?pn=1&ps=20&vmid=UID', {
headers: { 'Cookie': 'SESSDATA=' + sessdata }
});
const data = await resp.json();
json
{
"url": "https://...",
"mode": "gui|headless|stealth",
"title": "页面标题",
"content": "正文内容(前15000字)",
"images": ["图片URL列表"],
"links": [{"text": "链接文字", "href": "链接地址"}],
"loadTime": "1.23s"
}
A: 启动命令前加 DISPLAY=:0,见上文"启动 Chrome 调试实例"。
A: 页面是 SPA,JS 加载慢。加大延时:
javascript
await page.waitForTimeout(6000); // 默认 4000
A: Chrome 调试实例未启动或已退出。先启动 Chrome 再连接。
A: 小红书对详情页有强制校验,可用搜索结果页代替,或在 GUI Chrome 中手动打开一次详情页。
A: 确保 Chrome 调试实例使用的是已登录的 profile( --user-data-dir=$HOME/.config/google-chrome/Default)。
策略适用场景{ waitUntil: 'domcontentloaded' } + 4秒延时通用首选,适合大多数 SPA{ waitUntil: 'load' } + 2秒延时传统多资源页面{ waitUntil: 'commit' } + 5秒延时有大量长连接(WebSocket/轮询)的网站
不要用
networkidle——知乎、小红书等有长连接,networkidle 永远等不到。