Задача звучала скучно: собирать выдачу Google. Много, регулярно, через обычные резидентные прокси и без платных SERP API.
Первая версия честно открывала Chrome, вбивала запрос и получала капчу. Вторая получала капчу чуть реже. Где‑то между двадцатым экспериментом и вкладкой, которая съела 3 гигабайта памяти, стало понятно, что мы всё это время думали о Google неправильно.
В итоге получился открытый инструмент, google‑browser‑scraper (GitHub, MIT): настоящий Chrome под Patchright, который отдаёт выдачу в JSON. Но эта статья не про код. Она про то, что мы намерили по дороге, и про то, что не сработало. Конкретных рецептов обхода здесь не будет: только что мерили, как мерили и что увидели.
Сначала про то, как мы считали
Всё, что ниже, — это прогоны на сервере с Windows, через резидентные прокси, обычно новый IP на каждый тест. Успех — это когда Google отдал страницу с результатами. Капча, блок, «необычный трафик» — отказ. Отказ мы никогда не записываем как «0 результатов»: в JSON у каждой страницы есть явный вердикт. Звучит очевидно, но иначе о проблеме узнаёшь через неделю по странной статистике.
И одно правило, которое мы выучили больно: сравнивать варианты можно только в одном окне времени, вперемешку. У Google бывают дни, когда не проходит ничего, и дни, когда проходит половина. Если вариант А мерили во вторник, а Б в среду, вы сравнили вторник со средой.
Headless убивает всё, а мы искали причину где угодно, кроме него
Однажды контрольные прогоны перестали работать. Совсем.
Режим браузера |
Обслужено запросов |
|---|---|
headless |
0 из 35 |
обычное окно |
149 из 150 |
Сначала мы решили, что неудачный час. Потом — что неудачный день. Потом придумали третье объяснение. И только после гигабайта сожжённого трафика сравнили настройки с прогоном, который работал, и нашли --headless, который случайно попал в проверочный скрипт.
Мораль, которую я теперь повторяю себе каждый раз: если что‑то сломалось, сначала ищи, чем этот запуск отличается от работающего. Объяснение, которое хорошо звучит, — не то же самое, что причина.
Свежий браузер Google не любит. Браузер с историей — любит
Чистый профиль на чистом IP, который сразу идёт искать, проходит редко. Тот же профиль, который сначала походил по обычным сайтам, проходит в разы чаще:
Пропущено IP |
|
|---|---|
сразу в поиск |
11 из 44 |
сначала обычные сайты |
36 из 44 |
Важно оказалось не только куда ходить, но и как долго оставаться. Короткие визиты помогали заметно хуже, чем визиты, похожие на чтение. Когда мы удлинили их, доля пропущенных свежих IP выросла почти вдвое.
Цена у этого есть: прогрев одного IP стоит десятки мегабайт трафика. Поэтому вся остальная история — о том, как платить за него реже.
Google доверяет не IP, а профилю
Это главный эксперимент. Берём профиль браузера, который Google уже пропустил, и переносим его на другой, новый IP.
Что попало на новый IP |
Пропущено |
|---|---|
свежий профиль |
2 из 16 |
профиль, который Google уже пропустил |
23 из 35 |
тот же профиль, но без кук Google |
0 из 12 |
Новый IP, ни одного запроса с него раньше — и Google пропускает, если браузер «тот же». Убери куки Google — и доверие пропадает целиком.
Для меня это поменяло картину. IP — это проверка на входе, а репутацию несёт профиль. Отсюда и практическое следствие для любого скрейпера: прогретый профиль ценнее прогретого IP, и терять его на каждой смене прокси — значит каждый раз платить заново.
Один IP держит тысячу запросов, и каждый следующий дешевле
Сначала мы меняли IP каждые 10 запросов, «на всякий случай». Потом каждые 50. Потом решили наконец проверить, где предел.
Предела мы не нашли. За три с лишним тысячи запросов на уже пропущенных IP Google не отказал ни разу. Удержание заканчивалось, когда отваливался сам резидентный IP, а один IP отработал 1210 запросов подряд, и тест остановили мы, а не Google.
Бонус, которого мы не ждали: страница дешевеет по мере удержания, потому что прогревается кэш браузера.
Запросы на одном IP |
Трафик внутри страницы |
|---|---|
1–50 |
~0,9 MB |
51–100 |
~0,6 MB |
200+ |
~0,4 MB |
Бесконечно дешеветь она, конечно, не может. После ~200-го запроса цена встаёт на плато и стоит там тысячу запросов подряд. Всё общее (скрипты, стили, картинки Google) уже в кэше, а остаётся то, что уникально для каждого запроса: HTML выдачи, превью, фоновые запросы. Это не закэшировать, поэтому около 0,65 MB на запрос — потолок экономии даже для IP, который живёт вечно.
Кэш можно унести с собой
Раз страницу удешевляет кэш, а доверие живёт в профиле, коллега предложил очевидное: переносить на новый IP профиль вместе с кэшем. Проверили в одном окне, вперемешку:
Что перенесли на новый IP |
Трафик на поиск, всё включено |
|---|---|
профиль без кэша |
~1,1 MB |
профиль с кэшем |
~0,73 MB |
Минус треть трафика на старте каждого нового IP. Google это не смутило: в обоих вариантах обслужены все поиски.
Вкладка Google на 3 гигабайта
Когда мы стали держать один IP по 500+ запросов, скрейпер начал падать с MemoryError. Python был ни при чём. Журнал Windows показал, что процесс‑рендерер вкладки с Google вырос до 3,2 GB за 548 поисков. А после падения скрейпера этот процесс продолжал висеть и держать память.
Первая идея — открывать новую вкладку раз в N поисков — не сработала вообще: память росла с той же скоростью. Моя гипотеза (не проверенная): Chrome держит вкладки одного сайта в одном процессе, и новая вкладка садится в тот же раздутый процесс. Сработал только перезапуск браузера: память идёт пилой, кэш на диске остаётся, а Google после перезапуска продолжает пускать. С этим контрольный прогон на 1000 запросов в два браузера прошёл без единой ошибки памяти.
А время суток вообще важно?
Я был уверен, что да: у нас даже прогоны стояли на вечер, «потому что вечером Google добрее». По сырым цифрам так и выходило: вечером проходило вдвое больше, чем ночью.
Потом мы сравнили часы внутри одного дня, и разница почти исчезла: лучшее окно (16–19 UTC) выигрывает у среднего за день около трёх пунктов. «Вдвое» давали не часы, а дни: прогоны в плохие дни случайно чаще попадали на ночь. Время суток почти не важно. День важен очень. А прогретый браузер проходит в 84% случаев в любое время.
Что не сработало
Пожалуй, самая полезная часть.
Уходить со страницы сразу после чтения. Экономит 35–45% трафика, но Google начал отказывать посреди удержания у 3 IP из 10, а без этого — у 0 из 6. Не стоит того.
Прогреть в Chrome, а искать лёгким клиентом. Идея красивая: дорогой браузер только для прогрева, дальше curl_cffi или Obscura с теми же куками. 0 из 50. Google пускал Chrome и не пускал лёгкий клиент с той же «историей».
Новая вкладка вместо перезапуска браузера — см. выше.
Сколько это стоит
Контрольный прогон последней версии: 1000 запросов из 1000, около 1 GB резидентного трафика вместе с прогревом, 1 час 40 минут в два браузера на сервере с 4 ядрами. При длинном удержании IP — около 0,8 GB на тысячу. Это заметно дешевле премиальных SERP API, хотя и немного медленнее: около 8–10 секунд на запрос на один браузер против 3–5 секунд у API.
Что я вынес
Google оценивает браузер, а не IP. IP — проверка на входе.
Тот, кого Google уже пустил, может делать сотни запросов. Дорого только начало.
Если результат внезапно поменялся, ищите, что поменялось у вас, прежде чем винить Google.
Сравнивайте варианты только в одном окне времени. Дни у Google слишком разные.
Попробовать
pip install google-browser-scraper patchright install chromium google-browser-scraper search "best running shoes" \ --proxy "http://USER-session-{session}:PASS@gate.example.com:7000" \ -o results.jsonl
Нужен любой резидентный прокси со sticky‑сессиями. Все замеры в статье сделаны на прокси NodeMaven, с ними сессии настраиваются флагом --nodemaven. Ещё есть Docker‑образ, локальный HTTP API в привычном формате SERP API и MCP‑сервер, через который AI‑агент получает живой поиск Google.
Если у вас на других прокси или другой ОС получается иначе, напишите в issues. Мне правда интересно, где наши выводы не держатся.
Комментарии (6)

Jesus05
22.10.2026 16:12Не совсем по теме статьи т.к. в разрезе статьи я обычный пользователь.
Интересно, что последнее время на моей домашней машине ютуб(оно-же тоже гугл) стал меня периодически спрашивать, а не робот ли я. По сути у меня теперь стал не стабильный IP в остальном я обычный пользователь для гугла.
AnnSerba
Одно следствие из «доверие живёт в куках» стоит проговорить: на Windows профиль не переносится между машинами как папка. Ключ шифрования кук лежит в Local State и защищён DPAPI под конкретного пользователя, так что на другом сервере Chrome эти куки просто не расшифрует. Если прогретых профилей станет больше одного и вы захотите разложить их по машинам, греть придётся на каждой заново — либо тащить профиль вместе с учётной записью.
eri
Либо вырубить dpapi и получить переносимый профиль ;)
Или перенести вместе с профилем пользователя.
AnnSerba
Про перенос вместе с профилем пользователя — да, так делают, но это тащит и мастер-ключи DPAPI (%APPDATA%\Microsoft\Protect), и знание пароля учётки на целевой машине, то есть переезд пользователя, а не профиля браузера. «Вырубить DPAPI» без патча сборки не выйдет: ключ в Local State всё равно обёрнут, и подменять его придётся своей сборкой. Дешевле не переносить профиль, а снимать с него состояние сессии и переинжектить на новой машине — в Playwright это storageState, и профиль для прогрева остаётся локальным.
eri
Ещё можно юзера в домен и перемещаемый профиль;)
AnnSerba
С доменом и перемещаемым профилем — да, так и решается, если инфраструктура уже есть: мастер-ключи DPAPI едут вместе с профилем, и куки расшифруются на другой машине. Но для фермы скрейперов это дорого: нужен домен с контроллером, перемещаемый профиль на сотни мегабайт (один кеш Chrome чего стоит), и всё это ради того, чтобы не снимать storageState. Если Active Directory уже стоит, вариант рабочий; если нет, дешевле один раз экспортировать состояние сессии.