Если res.php вернул ERROR_WRONG_GOOGLEKEY, в девяти случаях из десяти дело не в API-ключе CaptchaAI, а в параметре googlekey: он устарел или взят не с той страницы.
Типичный сценарий: команда переносит парсер с 2Captcha на CaptchaAI, меняет endpoint и API-ключ, а googlekey оставляет из старого конфига. Первый прогон падает с ERROR_WRONG_GOOGLEKEY — сайт сменил sitekey. Дело не в коде интеграции, а в свежем извлечении ключа перед каждой задачей.
Эта ошибка почти никогда не значит, что сломан сам аккаунт CaptchaAI или тарифный план — баланс потоков и API-ключ тут ни при чём, проблема всегда в значении googlekey.
Из-за чего появляется эта ошибка
Причины делятся на три группы, и от того, к какой из них относится ваш случай, зависит план действий:
- Ключ вообще не тот — извлечён не с той страницы, из iframe или с чужого домена.
- Ключ тот, но нужен дополнительный параметр — Enterprise или invisible-версия reCAPTCHA требует явного флага в запросе.
- Ключ был верным, но устарел — сайт сменил sitekey после редизайна или ключ ротируется динамически.
Симптомы и что делать
Ключ выглядит правильно, но ошибка не пропадает
Чаще всего это Enterprise-ключ, отправленный как обычный. Проверьте, какой скрипт подключён на странице, и добавьте enterprise=1.
Ключ меняется от запуска к запуску
Sitekey динамический — сайт генерирует его на лету или ротирует. Извлекайте ключ заново перед каждой задачей, не кэшируйте его надолго.
На странице несколько sitekey сразу
Обычно это виджет формы логина плюс скрытый виджет формы регистрации или футера. Сопоставьте ключ вручную с той формой, которую вы реально отправляете.
Ключ извлечён из iframe CDN
Такой ключ нередко принадлежит другому домену, чем видимая страница. Извлекайте data-sitekey с основного документа, а не из URL iframe.
После извлечения sitekey пустой
Скорее всего sitekey рендерится через JavaScript уже после загрузки DOM. Статический парсинг HTML его не увидит — нужен headless-браузер (раздел ниже).
Как найти правильный sitekey
Ниже — три способа извлечения, от самого быстрого (поиск по исходнику) до самого надёжного для сайтов с JS-рендерингом.
Способ 1: поиск в исходном коде страницы
import re
import requests
def extract_sitekey(page_url):
"""Extract reCAPTCHA sitekey from page source."""
resp = requests.get(page_url, timeout=15)
html = resp.text
# Pattern 1: data-sitekey attribute
match = re.search(r'data-sitekey="([^"]+)"', html)
if match:
return match.group(1)
# Pattern 2: grecaptcha.render call
match = re.search(r"grecaptcha\.render\([^,]+,\s*\{[^}]*sitekey['\"]?\s*:\s*['\"]([^'\"]+)", html)
if match:
return match.group(1)
# Pattern 3: grecaptcha.execute call
match = re.search(r"grecaptcha\.execute\(['\"]([^'\"]+)", html)
if match:
return match.group(1)
# Pattern 4: reCAPTCHA script src
match = re.search(r"recaptcha/api\.js\?render=([^&\"]+)", html)
if match:
return match.group(1)
return None
sitekey = extract_sitekey("https://staging.example.com/qa-login")
print(f"Sitekey: {sitekey}")
Способ 2: DevTools браузера
- Откройте целевую страницу в Chrome
- Нажмите F12 → вкладку Элементы.
- Нажмите Ctrl+F и найдите
sitekey. - Найдите атрибут
data-sitekey="...". - Скопируйте значение (буквенно-цифровая строка из 40 символов)
Способ 3: вкладка «Сеть»
- Откройте вкладку F12 → Сеть.
- Фильтровать по
recaptcha - Ищите запросы на
google.com/recaptcha/api2/anchor - Найдите в URL-адресе параметр
k=— это ключ сайта.
Проверка sitekey перед отправкой задачи
Валидируйте sitekey до вызова API — это дешевле, чем ждать ошибку из очереди. Регулярка ниже не гарантирует, что ключ рабочий, но отсекает пустые строки и явно битые значения ещё до запроса:
import re
def validate_sitekey(sitekey):
"""Validate sitekey format before API call."""
if not sitekey:
raise ValueError("Sitekey is empty")
# Standard format: 40 alphanumeric + hyphens/underscores
if not re.match(r'^[a-zA-Z0-9_-]{20,60}$', sitekey):
raise ValueError(f"Invalid sitekey format: {sitekey}")
return True
# Use before solving
sitekey = extract_sitekey("https://staging.example.com/qa-login")
validate_sitekey(sitekey)
reCAPTCHA Enterprise: отдельный случай
Ключи Enterprise визуально не отличить от обычных — API нужно предупредить параметром enterprise:
import requests
# Standard reCAPTCHA — loads via recaptcha/api.js
# Enterprise reCAPTCHA — loads via recaptcha/enterprise.js
def detect_enterprise(page_url):
"""Detect if page uses reCAPTCHA Enterprise."""
resp = requests.get(page_url, timeout=15)
return "recaptcha/enterprise.js" in resp.text
# Submit with enterprise flag
is_enterprise = detect_enterprise("https://example.com")
data = {
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": "https://example.com",
"json": 1,
}
if is_enterprise:
data["enterprise"] = 1
resp = requests.post("https://ocr.captchaai.com/in.php", data=data)
Невидимая reCAPTCHA
Invisible reCAPTCHA не показывает виджет на странице до отправки формы, поэтому визуальным поиском её легко пропустить — ключ есть, но флаг invisible в запросе отсутствует, и API возвращает ту же ошибку ERROR_WRONG_GOOGLEKEY.
def detect_invisible(html):
"""Detect invisible reCAPTCHA."""
indicators = [
'data-size="invisible"',
"grecaptcha.execute(",
"recaptcha/api.js?render=",
]
return any(i in html for i in indicators)
# Submit with invisible flag
data = {
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": "https://example.com",
"invisible": 1,
"json": 1,
}
Динамический sitekey через headless-браузер
Часть сайтов подставляет sitekey через JavaScript уже после загрузки — статический поиск по исходнику вернёт пустоту. Здесь нужен headless-рендеринг:
from selenium import webdriver
from selenium.webdriver.common.by import By
def extract_dynamic_sitekey(url):
"""Extract sitekey from JavaScript-rendered page."""
driver = webdriver.Chrome()
driver.get(url)
# Wait for reCAPTCHA to load
import time
time.sleep(3)
# Try data-sitekey attribute
elements = driver.find_elements(By.CSS_SELECTOR, "[data-sitekey]")
if elements:
sitekey = elements[0].get_attribute("data-sitekey")
driver.quit()
return sitekey
# Try iframe src parameter
iframes = driver.find_elements(By.CSS_SELECTOR, "iframe[src*='recaptcha']")
for iframe in iframes:
src = iframe.get_attribute("src")
import re
match = re.search(r'[?&]k=([^&]+)', src)
if match:
driver.quit()
return match.group(1)
driver.quit()
return None
Чек-лист перед обращением в поддержку
Прежде чем открывать тикет, стоит пройти по короткому списку — большинство случаев ERROR_WRONG_GOOGLEKEY закрываются на этом этапе без переписки с поддержкой:
- Извлеките sitekey заново прямо сейчас, а не берите значение из конфига недельной давности.
- Сверьте
pageurlв запросе с тем же доменом, с которого извлечён ключ, — ключ отexample.comне подойдёт дляapp.example.com. - Проверьте, не грузится ли на странице
recaptcha/enterprise.js— если да, добавьтеenterprise=1. - Проверьте наличие
data-size="invisible"или вызоваgrecaptcha.execute(— это признак invisible-версии, нуженinvisible=1. - Если ключ рендерится через JavaScript и статический поиск возвращает пустоту, переходите на headless-извлечение через Selenium.
- Прогоните запрос на staging-копии страницы, а не на боевом сайте, чтобы не тратить потоки на заведомо неверный ключ во время отладки.
Сводная таблица причин
| Причина | Как определить |
|---|---|
| Извлечен неверный ключ сайта. | Ключ не соответствует источнику страницы |
| Ключ корпоративного сайта отправляется в стандартной комплектации | Нужен параметр enterprise=1 |
| Невидимое несоответствие ключей reCAPTCHA | Нужен параметр invisible=1 |
| Динамический ключ сайта изменен. | Ключ повернут с момента извлечения |
| Неправильный ключ сайта страницы | Извлечено из iframe или другого домена. |
| Жестко закодированный устаревший ключ сайта | Ключ был действителен ранее |
Часто задаваемые вопросы
Почему ERROR_WRONG_GOOGLEKEY появляется, если sitekey скопирован правильно?
Он был верным на момент извлечения, но сайт его сменил — после редизайна формы логина или миграции на другой домен. Извлекайте sitekey заново перед каждым прогоном, а не храните его в статичном конфиге.
На каком домене искать sitekey, если reCAPTCHA подгружается через iframe с другого поддомена?
Со страницы, которую видит пользователь, а не из URL iframe — виджет часто рендерится с google.com, но привязан к sitekey родительской страницы.
Подходит ли один и тот же sitekey для reCAPTCHA v2 и v3?
Нет, версии используют разные sitekey даже на одном сайте. Версию проще определить по скрипту — recaptcha/api.js без render= обычно v2, а с render= — v3.
Нужно ли кэшировать sitekey между запросами?
Можно, но недолго — минуты, максимум пара часов. Если решение задач начало массово падать с этой ошибкой, сбросьте кэш и извлеките sitekey заново.
Как быстро отличить Enterprise-ключ от обычного, не читая весь исходник страницы?
Проверьте, какой скрипт подключён: recaptcha/api.js — обычная reCAPTCHA, recaptcha/enterprise.js — Enterprise. Это быстрее, чем сравнивать сам ключ визуально.
Похожие материалы
Настройте свежее извлечение sitekey перед каждой задачей — решайте reCAPTCHA с CaptchaAI.