Как решать капчу в n8n с помощью узла HTTP Request

Отдельного узла CAPTCHA в n8n нет, и он вам не нужен. Два узла HTTP Request и узел Wait решают любой поддерживаемый тип капчи: первый отправляет задание, второй опрашивает результат, пока не вернётся токен. Направьте оба на 127.0.0.1:8080 и весь цикл выполняется на той же машине, что и n8n, поэтому ничего не покидает вашу сеть и ничего не тарифицируется за каждое решение. CapSkip также работает на сервере и принимает те же API-запросы по сети, и именно так его используют из n8n Cloud. В этом руководстве рабочий процесс собирается нода за нодой, включая ловушку с сетью Docker, на которой большинство спотыкается при первом запуске.
Что понадобится
- n8n: self-hosted, десктоп или облако. Все три варианта работают, но для облака нужно, чтобы CapSkip был доступен по сети. См. раздел о сервере ниже.
- Приложение CapSkip запущено, служба работает. Порт, ключ и режим Local или Server находятся в разделе Настройки подключения.
- sitekey и URL страницы того сайта, который вы автоматизируете.
Проверка ключа по умолчанию отключена, поэтому в качестве параметра key подойдёт любая непустая строка. Всё же отправьте что-нибудь, а не пустоту: при пустом ключе возвращается ERROR_WRONG_USER_KEY.
Почему HTTP Request, а не community-узел
Community-узлы нужно устанавливать на инстанс, они отстают от изменений API, а в n8n Cloud они ограничены. Здешний API совместим с 2captcha и имеет всего две конечные точки, так что community-узел обернул бы примерно шесть строк конфигурации. Встроенный узел HTTP Request делает ту же работу, обновляется вместе с n8n и работает на любом типе инстанса.
| Эндпоинт | Что делает | Возвращает |
|---|---|---|
/in.php | Отправляет задачу | Числовой ID капчи |
/res.php | Спрашивает, готов ли этот ID | Токен или строка CAPCHA_NOT_READY |
Шаг 1: отправляем капчу
Добавьте узел HTTP Request и назовите его Submit CAPTCHA. Задайте метод POST, а в качестве URL укажите http://127.0.0.1:8080/in.php. Включите Send Body, выберите Form Urlencoded и добавьте эти поля.
| Имя | Значение |
|---|---|
| key | Любая непустая строка |
| method | userrecaptcha |
| googlekey | Ваш sitekey |
| pageurl | Страница, на которой расположен виджет |
| json | 1 |
Всегда отправляйте поле json. Без него ответ приходит простой строкой вида OK|2122988149 такую строку приходится разбирать вручную. С этим полем вы получаете объект, к которому n8n может обращаться напрямую.
// Response from in.php with json=1
{"status": 1, "request": "2122988149"}
// The captcha ID is now available downstream as:
// {{ $json.request }}Другие типы капчи меняют только поле method и соседние с ним параметры. Turnstile использует turnstile с парой sitekey и pageurl, GeeTest использует geetest с gt и challenge, а капча-картинка использует base64 с байтами изображения в поле тела запроса. Справочник по API перечисляет все параметры для каждого типа.
Шаг 2: пауза перед первым опросом
Добавьте узел Wait после Submit CAPTCHA. Задайте Resume в After Time Interval, Wait Amount в 15, а Wait Unit в секунды.
Пятнадцать секунд взяты не с потолка. Задание reCAPTCHA v2 редко готово раньше, поэтому немедленный опрос просто расходует итерацию воркфлоу на гарантированный CAPCHA_NOT_READY. Turnstile и GeeTest проходят быстрее, там достаточно 5 секунд. Капча-картинка обычно готова примерно за секунду.
Шаг 3: опрашиваем результат
Добавьте второй узел HTTP Request с именем Poll Result. Метод GET, URL: http://127.0.0.1:8080/res.php, включите Send Query Parameters.
| Имя | Значение |
|---|---|
| key | Та же строка, что и на шаге 1 |
| action | get |
| id | {{ $('Submit CAPTCHA').item.json.request }} |
| json | 1 |
Ссылайтесь на узел отправки по имени, а не через $json.request. Как только между ними появляется узел Wait, входящий элемент принадлежит узлу Wait, а на втором проходе цикла он принадлежит узлу IF. Явное указание исходного узла по имени сохраняет ID неизменным, сколько бы раз ни выполнился цикл.
Шаг 4: цикл до готовности
Добавьте узел IF после Poll Result. Условие представляет собой сравнение строк: левое значение {{ $json.request }}, операция “is not equal to”, правое значение CAPCHA_NOT_READY.
Подключите выход false обратно к узлу Wait. Так замыкается цикл, и n8n продолжает опрос, пока не придёт ответ. Выход true передаёт токен дальше.
// res.php while the job is still running
{"status": 0, "request": "CAPCHA_NOT_READY"}
// res.php once it is solved
{"status": 1, "request": "03AGdBq26..."}Обратите внимание на написание. API возвращает CAPCHA_NOT_READY без первой T. Это наследие формата 2captcha, с которым он совместим. Если напишете так, как кажется правильным, узел IF никогда не совпадёт, и цикл будет крутиться, пока воркфлоу не завершится по таймауту.
Результат читается только один раз. Повторное чтение того же ID вернёт ошибку, а не токен ещё раз, поэтому передавайте токен сразу в следующий узел, а не опрашивайте сначала для проверки, а потом ещё раз для получения.
Шаг 5: используем токен
Ветка true узла IF теперь несёт токен. Отправьте его в поле формы g-recaptcha-response в том запросе, который у вас блокировали, с помощью третьего узла HTTP Request.
// Code node, Mode: Run Once for All Items.
// Builds the form payload for the final request.
const token = $input.first().json.request;
return [
{
json: {
email: "[email protected]",
"g-recaptcha-response": token,
},
},
];Токены истекают примерно через две минуты после выдачи, поэтому отправляйте запрос сразу. Если между решением и отправкой в воркфлоу есть шаг согласования или ещё один узел Wait, перенесите решение капчи после него.
Ловушка Docker: localhost указывает не на вашу машину
Это самая частая причина сбоя, и сообщение об ошибке не указывает ни на что полезное. Внутри контейнера 127.0.0.1 означает сам контейнер, а не хост, на котором работает решатель. n8n сообщает об отказе в соединении, и воркфлоу падает на узле Submit CAPTCHA.
В Docker Desktop для Mac и Windows замените хост на host.docker.internal в обоих URL. В Linux это имя по умолчанию не разрешается, поэтому добавьте его явно при запуске контейнера.
# docker pull docker.n8n.io/n8nio/n8n # Linux: map host.docker.internal to the host gateway. docker run -it --rm \ --add-host=host.docker.internal:host-gateway \ -p 5678:5678 \ -v n8n_data:/home/node/.n8n \ docker.n8n.io/n8nio/n8n # Both node URLs then become: # http://host.docker.internal:8080/in.php # http://host.docker.internal:8080/res.php
Если n8n и решатель работают в одной сети Docker, используйте вместо этого имя сервиса. Правило в любом случае одно: URL должен разрешаться изнутри контейнера, а не из вашего терминала.
Запуск CapSkip на отдельном сервере
CapSkip не обязательно должен работать на той же машине, что и n8n. Настройки подключения имеют два режима, и именно второй позволяет работать с облачным n8n.
| Режим | Прослушивает | Когда использовать |
|---|---|---|
| Локально | 127.0.0.1, только это устройство | n8n и CapSkip работают на одном компьютере |
| Сервер | Вашу сеть или публичный IP | n8n работает в другом месте: на другой машине, на VPS или в n8n Cloud |
Разместите CapSkip на VPS в режиме Server, и все машины вашей команды будут обращаться к одному экземпляру. URL-адреса нод примут вид http://YOUR_SERVER_IP:8080/in.php и http://YOUR_SERVER_IP:8080/res.php, и больше ничего в рабочем процессе не меняется. Статический публичный IP стоит завести, поскольку URL-адреса жёстко прописаны в нодах, а смена адреса их ломает.
Это всё ещё ваше собственное оборудование, и тарификации по-прежнему нет. Режим Server меняет только то, где работает решатель, а не то, кому он принадлежит, поэтому в любом случае вы не платите за каждое решение.
Частые ошибки и что они означают
| Ответ | Причина | Исправить |
|---|---|---|
ECONNREFUSED | Решатель не запущен или контейнер не видит хост | Запустите локальный сервис, затем примените описанное выше исправление для Docker |
ERROR_WRONG_USER_KEY | Поле key пустое или отсутствует | Отправьте любую непустую строку |
ERROR_GOOGLEKEY | sitekey неверный, обрезан или взят с другой страницы | Считайте атрибут data-sitekey заново на живой странице |
ERROR_PAGEURL | В поле pageurl отсутствует схема, либо оно указывает не туда | Отправляйте полный URL вместе с https |
| Цикл никогда не завершается | Узел IF сравнивает со строкой готовности, написанной с ошибкой | Точно соблюдайте написание CAPCHA_NOT_READY |
ERROR_CAPTCHA_UNSOLVABLE | Задание завершилось ошибкой, а не по таймауту | Отправьте задание заново со свежим значением challenge |
Каждый код, который может вернуть API, перечислен в Документация по API, с параметром, который вызывает каждую из них.
FAQ
Работает ли это в n8n Cloud?
Да, если CapSkip работает в режиме Server. Облачные воркеры работают в инфраструктуре n8n, поэтому они не видят 127.0.0.1 на вашем компьютере, а это единственный адрес, который допускает режим Local. Переключите настройки подключения в режим Server, запустите CapSkip на VPS со статическим публичным IP и укажите нодам этот адрес. Если вы предпочитаете держать всё на одной машине, поднимите self-hosted n8n рядом с ним и оставайтесь в режиме Local.
Во сколько выполнений обходится цикл опроса?
В одно. Цикл внутри воркфлоу остаётся одним выполнением, сколько бы витков он ни сделал, поэтому пара Wait и IF не умножает число ваших выполнений. Но она держит выполнение открытым, а это важно, если вы запускаете много воркфлоу одновременно на небольшом инстансе.
Можно ли решить несколько капч за один запуск?
Да. Узел HTTP Request выполняется один раз на каждый входной элемент, поэтому если подать ему список пар sitekey и URL, он отправит их все и вернёт по одному ID капчи на элемент. Держите ID связанными с их исходными элементами на протяжении всего цикла и используйте узел Split In Batches, если хотите ограничить, сколько заданий обрабатывается одновременно.
Нужен ли мне прокси?
Обычно нет. Добавляйте поля proxy и proxytype в узел отправки только тогда, когда целевой сайт отклоняет токены, решённые из сети, отличной от той, что загрузила страницу. Прокси применимы к reCAPTCHA, Turnstile и GeeTest и игнорируются для капч-картинок.
Как встроить это в реальный воркфлоу
Пять описанных выше узлов вставляются в любой воркфлоу, который упирается в защищённую форму: парсер для сбора лидов, ночная проверка цен, внутренний инструмент, который логинится в устаревший портал. Поскольку решатель работает как распознавание капчи и всё работает на вашем собственном оборудовании, sitekey и URL страниц, которые вы ему передаёте, никогда не покидают машину, а цикл ничего не стоит за запуск. Если вы предпочитаете вызывать его из узла Code на JavaScript или Python, а не через узлы HTTP Request, официальные SDK оборачивают те же две конечные точки, а особенности reCAPTCHA v2 разбираются отдельно.
