通过Puppeteer使用Chrome开发者工具协议(CDP)控制本地Chrome浏览器。适用于需要自动化执行浏览器任务(如页面导航、点击等)的场景。
Control and automate a Chrome browser that's already running with CDP enabled, using Puppeteer.
Chrome must be running with remote debugging enabled. If not already started:
bash
# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 &
# Windows
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222
# Linux
google-chrome --remote-debugging-port=9222 &
Visit http://localhost:9222/json/version to get the webSocketDebuggerUrl, for example:
text
ws://127.0.0.1:9222/devtools/browser/FFA7276F8E8E51645BD2AC9BE6B79607
Or use this one-liner:
bash
curl -s http://localhost:9222/json/version | grep -o '"webSocketDebuggerUrl":"[^"]*"' | cut -d'"' -f4
bash
cd chrome-cdp-controller
npm install
This installs puppeteer-core which is lightweight (doesn't download Chromium).
Create a JSON file with commands:
commands.json:
json
[
{"type": "navigate", "url": "https://www.baidu.com"},
{"type": "wait", "seconds": 2},
{"type": "screenshot", "path": "/tmp/screenshot.png"},
{"type": "evaluate", "script": "document.title"}
]
Execute:
bash
node scripts/cdp_controller.js --ws "ws://127.0.0.1:9222/devtools/browser/..." --commands commands.json
javascript
const { CDPController } = require('./scripts/cdp_controller.js');
(async () => {
const controller = new CDPController('ws://127.0.0.1:9222/devtools/browser/...');
await controller.connect();
// Navigate
await controller.navigate('https://www.taobao.com');
// Fill form
await controller.fill('#q', 'iPhone');
await controller.press('Enter');
await controller.wait(3);
// Extract data
const result = await controller.evaluate(`
Array.from(document.querySelectorAll('.item'))
.slice(0, 10)
.map(item => ({
title: item.querySelector('.title')?.textContent.trim(),
price: item.querySelector('.price')?.textContent.trim()
}))
`);
console.log(result.result);
// Intercept network
await controller.startIntercept('*api*');
// ... perform actions ...
const responses = controller.getInterceptedResponses();
await controller.close();
})();
navigate - Go to URL
url: Target URLwaitUntil: "load", "domcontentloaded", or "networkidle2" (default)selector: CSS selectortimeout: Timeout in milliseconds (default: 5000)selector: CSS selectortext: Text to filltimeout: Timeout in milliseconds (default: 5000)selector: CSS selectortext: Text to typedelay: Delay between characters in ms (default: 50)timeout: Timeout in milliseconds (default: 5000)key: Key name (Enter, Tab, Escape, etc.)selector: CSS selectorselector: CSS selectorscript: JavaScript codestart_intercept - Start intercepting network responses
url_pattern: URL pattern to match (substring match, e.g., "api")get_intercepted - Get all intercepted responses
clear_intercepted - Clear intercepted responses list
path: Output file pathfullPage: Capture full page (default: false)selector: CSS selectortimeout: Timeout in milliseconds (default: 5000)seconds: Number of seconds to waittaobao-search.json:
json
[
{"type": "navigate", "url": "https://www.taobao.com"},
{"type": "wait", "seconds": 2},
{"type": "fill", "selector": "#q", "text": "iPhone"},
{"type": "press", "key": "Enter"},
{"type": "wait", "seconds": 5},
{"type": "evaluate", "script": "Array.from(document.querySelectorAll('.item, [class*=\"Item\"]')).slice(0, 10).map(item => ({ title: item.querySelector('.title, [class*=\"title\"]')?.textContent.trim().substring(0, 80), price: item.querySelector('.price, [class*=\"price\"]')?.textContent.trim() }))"}
]
Run:
bash
WS_URL=$(curl -s http://localhost:9222/json/version | grep -o '"webSocketDebuggerUrl":"[^"]*"' | cut -d'"' -f4)
node scripts/cdp_controller.js --ws "$WS_URL" --commands taobao-search.json
Note: Selectors may vary. Use browser DevTools (F12) to inspect elements.
chatgpt-ask.json:
json
[
{"type": "navigate", "url": "https://chat.openai.com"},
{"type": "wait_for_selector", "selector": "textarea", "timeout": 10000},
{"type": "type", "selector": "textarea", "text": "What is artificial intelligence?"},
{"type": "press", "key": "Enter"},
{"type": "wait", "seconds": 10},
{"type": "get_text", "selector": "[data-message-author-role='assistant']:last-of-type"}
]
intercept-api.json:
json
[
{"type": "start_intercept", "url_pattern": "graphql"},
{"type": "navigate", "url": "https://example.com"},
{"type": "wait", "seconds": 3},
{"type": "get_intercepted"}
]
For more examples, see references/examples.md.
When automating browser tasks:
ws://127.0.0.1:9222/devtools/browser/...), use it directlyhttp://localhost:9222/json/versionevaluate with document.querySelector to test selectorsnavigatewait or wait_for_selector between stepsfill for form inputs, click for buttonsevaluate for complex data extractionstart_intercept before navigation if monitoring network trafficnode scripts/cdp_controller.js --ws "<websocket-url>" --commands <file>wait_for_selectorwait_for_selector instead of fixed wait when possible#id) > class ( .class) > attribute ( [attr='value'])evaluate for complex data extraction--remote-debugging-port=9222wait_for_selector before interactionbash
cd chrome-cdp-controller
npm install