feat: human-like typing for browser Google and YouTube search
Some checks failed
Release / semantic-release (push) Successful in 26s
tests / Unit tests (Linux, Python 3.11) (push) Failing after 5m16s
Release / build-linux (push) Failing after 7m11s
Release / build-windows (push) Has been cancelled
Release / build-macos (arm64, macos-latest) (push) Has been cancelled
Release / build-macos (x64, macos-15-intel) (push) Has been cancelled
Release / release-main (push) Has been cancelled
Release / release-develop (push) Has been cancelled
Some checks failed
Release / semantic-release (push) Successful in 26s
tests / Unit tests (Linux, Python 3.11) (push) Failing after 5m16s
Release / build-linux (push) Failing after 7m11s
Release / build-windows (push) Has been cancelled
Release / build-macos (arm64, macos-latest) (push) Has been cancelled
Release / build-macos (x64, macos-15-intel) (push) Has been cancelled
Release / release-main (push) Has been cancelled
Release / release-develop (push) Has been cancelled
Make the browser search helper search the way a person does: load the site home page, type the query into the search box one key at a time, and press Enter — for both Google `search` and `youtube` — instead of jumping straight to a results URL. Supports the goal of a human-like assistant. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -87,13 +87,26 @@ async function closeAll() {
|
||||
try { await connected?.close(); } catch { /* ignore */ }
|
||||
}
|
||||
|
||||
// Human-like search: land on the site's home page, type the query into its
|
||||
// search box one key at a time, and press Enter — the way a person would,
|
||||
// rather than jumping straight to a results URL.
|
||||
async function typeSearch(homeUrl, boxSelector, query) {
|
||||
await page.goto(homeUrl, { waitUntil: 'domcontentloaded' });
|
||||
const box = page.locator(boxSelector).first();
|
||||
await box.waitFor({ timeout: 15000 });
|
||||
await box.click();
|
||||
await box.pressSequentially(query, { delay: 45 });
|
||||
await box.press('Enter');
|
||||
}
|
||||
|
||||
try {
|
||||
await acquirePage();
|
||||
page.setDefaultTimeout(20000);
|
||||
await page.bringToFront().catch(() => {});
|
||||
|
||||
if (mode === 'youtube') {
|
||||
await page.goto(`https://www.youtube.com/results?search_query=${encodeURIComponent(query)}`, { waitUntil: 'domcontentloaded' });
|
||||
// Type into YouTube's search box like a person, then play the first result.
|
||||
await typeSearch('https://www.youtube.com/?hl=ko', 'input#search, input[name="search_query"]', query);
|
||||
await page.waitForSelector('ytd-video-renderer a#video-title, a#video-title', { timeout: 20000 });
|
||||
const first = page.locator('ytd-video-renderer a#video-title, a#video-title').first();
|
||||
const title = (await first.getAttribute('title').catch(() => '')) || (await first.innerText().catch(() => ''));
|
||||
@@ -102,7 +115,9 @@ try {
|
||||
await page.evaluate(() => { const v = document.querySelector('video'); if (v && v.paused) v.play(); });
|
||||
out({ ok: true, mode, title: (title || '').trim(), url: page.url() });
|
||||
} else {
|
||||
await page.goto(`https://www.google.com/search?q=${encodeURIComponent(query)}&hl=ko`, { waitUntil: 'domcontentloaded' });
|
||||
// Type into Google's search box like a person, then read the results.
|
||||
await typeSearch('https://www.google.com/?hl=ko', 'textarea[name="q"], input[name="q"]', query);
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
await page.waitForTimeout(1500);
|
||||
// Google serves its bot-detection interstitial (/sorry/index) to sessions it
|
||||
// suspects are automated. Detect it structurally (by URL, locale-independent)
|
||||
|
||||
@@ -22,7 +22,10 @@ path (evals, text entry) and falls back to the master flag:
|
||||
|
||||
- **on-screen Chrome**: `browser_search()` drives Chrome (Node CDP helper
|
||||
`bot/scripts/stream-test/browse-search.mjs`) to Google-search the query, so
|
||||
the action is visible on the Go-Live broadcast. When no broadcast Chrome is
|
||||
the action is visible on the Go-Live broadcast. The helper searches the
|
||||
human way — it loads the site home page, types the query into the search box
|
||||
one key at a time, and presses Enter (both Google `search` and `youtube`),
|
||||
rather than jumping to a results URL. When no broadcast Chrome is
|
||||
reachable on CDP (e.g. a plain text turn with no active broadcast), the helper
|
||||
falls back, for `search` only, to launching its own Chrome so browser-based
|
||||
Google search still works with no API cost. Fallback order:
|
||||
|
||||
Reference in New Issue
Block a user