Install
openclaw skills install @lgx-00/google-index-checkerCheck Google indexed page count for any domain using the "site:" search operator in Chrome Remote Debugging Protocol (CDP on localhost:9222). Use when the user wants to check how many pages Google has indexed for a website, compare indexing across multiple domains, or monitor SEO indexing status. Supports single or multiple domains with comparison table output.
openclaw skills install @lgx-00/google-index-checkerCheck the number of indexed pages for any domain(s) using Google's site: search operator via Chrome Remote Debugging Protocol (CDP) on localhost:9222.
--remote-debugging-port=9222ws npm package available at /tmp/wsclient/node_modules/ws
npm install ws --prefix /tmp/wsclienthttp://localhost:9222/jsonlocalhost:9222, NOT 127.0.0.1:9222 — Chrome listens on IPv6 ::1, not IPv4 127.0.0.1/tmp/wsclientExtract the domain(s) to check. Accept:
example.com, www.example.com, https://example.comws if needed: npm install ws --prefix /tmp/wsclientPUT http://localhost:9222/json/newwebSocketDebuggerUrl from the responseFor each domain, use Page.navigate in the same tab (do NOT create new tabs):
Page.navigate → https://www.google.com/search?q=site:{domain}Page.loadEventFired + 3 secondsRuntime.evaluate → document.getElementById('result-stats')?.textContent"找到约 12,700 条结果" using regex /找到约 ([\d,]+) 条结果/**{domain}** has approximately **{count}** pages indexed by Google.
## Google Index Coverage Report ({date})
| Domain | Indexed Pages | Notes |
|--------|--------------|-------|
| example.com | 13,200 | — |
| example.org | 8,500 | — |
| example.net | 1,200 | — |
Data source: Google `site:` search operator (approximate values)
DELETE http://localhost:9222/json/close/{targetId}GET http://localhost:9222/json should return []rm -rf /tmp/wsclientconst WebSocket = require('/tmp/wsclient/node_modules/ws');
const http = require('http');
function cdpSend(ws, id, method, params) {
return new Promise(resolve => {
const handler = data => {
const msg = JSON.parse(data);
if (msg.id === id) resolve(msg);
};
ws.on('message', handler);
ws.send(JSON.stringify({id, method, params}));
});
}
function extractCount(text) {
if (!text) return 'NOT_FOUND';
const m = text.match(/找到约 ([\d,]+) 条结果/);
return m ? m[1].replace(/,/g, '') : 'PARSE_ERROR:' + text;
}
async function main() {
// 1. Create one tab
const target = await new Promise((resolve, reject) => {
const req = http.request({hostname: 'localhost', port: 9222, path: '/json/new', method: 'PUT'}, res => {
let d = ''; res.on('data', c => d += c); res.on('end', () => resolve(JSON.parse(d)));
});
req.on('error', reject); req.end();
});
// 2. Connect WebSocket
const ws = new WebSocket(target.webSocketDebuggerUrl);
await new Promise(r => ws.on('open', r));
await cdpSend(ws, 1, 'Page.enable', {});
await cdpSend(ws, 2, 'Runtime.enable', {});
// 3. Loop through domains
const domains = [['Name', 'example.com']]; // Replace with actual domains
for (const [name, domain] of domains) {
await cdpSend(ws, 10, 'Page.navigate', {url: 'https://www.google.com/search?q=site:' + domain});
await new Promise(resolve => {
ws.on('message', data => {
const msg = JSON.parse(data);
if (msg.method === 'Page.loadEventFired') resolve();
});
});
await new Promise(r => setTimeout(r, 3000));
const r = await cdpSend(ws, 11, 'Runtime.evaluate', {expression: "document.getElementById('result-stats')?.textContent || 'NOT_FOUND'"});
console.log(name + '|' + domain + '|' + extractCount(r.result.result.value));
}
// 4. Cleanup
ws.close();
http.request({hostname: 'localhost', port: 9222, path: '/json/close/' + target.id, method: 'DELETE'}, () => {}).end();
await new Promise(r => setTimeout(r, 1000));
// 5. Verify tabs closed
const remaining = await new Promise((resolve, reject) => {
const req = http.request({hostname: 'localhost', port: 9222, path: '/json', method: 'GET'}, res => {
let d = ''; res.on('data', c => d += c); res.on('end', () => resolve(JSON.parse(d)));
});
req.on('error', reject); req.end();
});
console.log('Tabs remaining:', remaining.length);
process.exit(0);
}
main().catch(e => { console.error(e); process.exit(1); });
| Problem | Solution |
|---|---|
#result-stats not found | Try div[id^=result] or document.body.innerText |
| Google CAPTCHA | Take screenshot, stop, report to user |
| 0 results | Check if site is new or blocked by robots.txt |
localhost:9222 returns 404 | Chrome not started with --remote-debugging-port=9222 |
| Tabs accumulate | Always close tab after use, verify with GET /json |
site: operator returns approximate values, not exact counts