Эта статья была полезной?
Как обойти MTCaptcha на сайте Checkinhoudingsplicht
Технический специалист
Сайт Checkinhoudingsplicht (checkinhoudingsplicht.be) — это официальный бельгийский правительственный портал для работодателей. Он используется для проверки и подтверждения соблюдения обязанности по проверке статуса проживания иностранных работников (так называемая houdingsplicht). Для защиты своих форм от автоматизации и ботов сайт использует систему MTCaptcha.
Эта капча представляет собой интерактивный виджет, который оценивает поведение пользователя. Для успешного решения через API v2 необходимо извлечь публичный ключ сайта (sitekey) и передать его вместе с полным URL страницы. В этом руководстве мы разберем, как найти эти параметры, отправить задачу и корректно внедрить полученный токен.
Параметры задачи (API v2)
Для отправки задачи через современный API v2 используется эндпоинт createTask. Объект task должен содержать следующие параметры:
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| type | String | Да | Тип задачи: MTCaptchaTaskProxyless или MTCaptchaTask |
| websiteURL | String | Да | Полный URL страницы, где находится капча |
| websiteKey | String | Да | Публичный ключ сайта MTCaptcha (начинается с MTPublic-) |
Как найти параметры
Параметры для MTCaptcha являются статическими для конкретной страницы и легко извлекаются из исходного кода.
- Откройте сайт https://www.checkinhoudingsplicht.be/ в браузере.
- Нажмите F12, чтобы открыть Инструменты разработчика (DevTools), и перейдите на вкладку Элементы (Elements).
- Нажмите Ctrl+F (или Cmd+F) и выполните поиск по фразе mt-captcha или data-sitekey.
- Вы найдете div-элемент, похожий на этот:
- Значение атрибута data-sitekey (в данном примере MTPublic-QPs1BHRjl) является вашим websiteKey.
- Скопируйте полный URL из адресной строки браузера. Это будет ваш websiteURL.
Примеры кода
Python + requests (API v2)
Пример отправки задачи и опроса результата с использованием библиотеки requests через эндпоинты API v2.
python
import requests
import time
API_KEY = 'ВАШ_API_КЛЮЧ'
WEBSITE_URL = 'https://www.checkinhoudingsplicht.be/'
WEBSITE_KEY = 'MTPublic-QPs1BHRjl'
# 1. Создание задачи через API v2
url = 'https://api.2captcha.com/createTask'
headers = {
'Content-Type': 'application/json'
}
payload = {
"clientKey": API_KEY,
"task": {
"type": "MTCaptchaTaskProxyless",
"websiteURL": WEBSITE_URL,
"websiteKey": WEBSITE_KEY
}
}
response = requests.post(url, headers=headers, json=payload)
result = response.json()
if result.get('errorId') == 0:
task_id = result.get('taskId')
print(f"Задача создана, ID: {task_id}")
# 2. Получение результата через API v2
res_url = 'https://api.2captcha.com/getTaskResult'
while True:
time.sleep(5) # Пауза между запросами
res_payload = {
"clientKey": API_KEY,
"taskId": task_id
}
res_response = requests.post(res_url, headers=headers, json=res_payload).json()
if res_response.get('errorId') == 0 and res_response.get('status') == 'ready':
print("Капча успешно решена!")
token = res_response['solution']['token']
print(f"Токен: {token}")
break
elif res_response.get('errorId') != 0:
print(f"Ошибка: {res_response.get('errorDescription')}")
break
else:
# Статус processing - задача еще не готова
continue
else:
print(f"Ошибка создания задачи: {result.get('errorDescription')}")
Python + Playwright
Пример автоматизации, который динамически извлекает sitekey со страницы, отправляет задачу через API v2 и внедряет токен.
python
from playwright.sync_api import sync_playwright
import requests
import time
API_KEY = 'ВАШ_API_КЛЮЧ'
TARGET_URL = 'https://www.checkinhoudingsplicht.be/'
def solve_mtcaptcha():
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
try:
page.goto(TARGET_URL)
# Ожидаем появления виджета MTCaptcha
page.wait_for_selector('.mt-captcha', timeout=10000)
# Извлекаем sitekey из атрибута data-sitekey
site_key = page.evaluate("""
() => {
const captchaDiv = document.querySelector('.mt-captcha');
return captchaDiv ? captchaDiv.getAttribute('data-sitekey') : null;
}
""")
if not site_key:
raise Exception("Не удалось найти sitekey MTCaptcha на странице.")
print(f"Найден sitekey: {site_key}")
# Отправка в API v2
api_url = 'https://api.2captcha.com/createTask'
headers = {'Content-Type': 'application/json'}
payload = {
"clientKey": API_KEY,
"task": {
"type": "MTCaptchaTaskProxyless",
"websiteURL": page.url,
"websiteKey": site_key
}
}
task_response = requests.post(api_url, headers=headers, json=payload).json()
if task_response.get('errorId') != 0:
raise Exception(f"Ошибка создания задачи: {task_response.get('errorDescription')}")
task_id = task_response.get('taskId')
# Ожидание решения через getTaskResult
res_url = 'https://api.2captcha.com/getTaskResult'
token = None
for _ in range(20):
time.sleep(5)
res = requests.post(res_url, headers=headers, json={"clientKey": API_KEY, "taskId": task_id}).json()
if res.get('status') == 'ready':
token = res['solution']['token']
break
if res.get('errorId') != 0:
print(f"Ошибка API: {res.get('errorDescription')}")
break
if token:
print(f"Токен получен: {token}")
# Внедрение токена в форму
# MTCaptcha обычно ожидает токен в скрытом поле с именем mt-captcha-response
page.evaluate(f"""
let input = document.querySelector('input[name="mt-captcha-response"]');
if (!input) {{
input = document.createElement('input');
input.type = 'hidden';
input.name = 'mt-captcha-response';
document.querySelector('form')?.appendChild(input);
}}
input.value = "{token}";
// Иногда требуется вызвать callback, если он определен
if (typeof window.mtCaptchaVerified === 'function') {{
window.mtCaptchaVerified("{token}");
}}
""")
print("Токен внедрен в DOM.")
else:
print("Не удалось получить токен.")
except Exception as e:
print(f"Ошибка: {e}")
finally:
# browser.close()
if __name__ == '__main__':
solve_mtcaptcha()
Альтернативный метод решения
В некоторых случаях, если стандартный метод MTCaptcha сталкивается с трудностями или специфическими защитами, можно попробовать альтернативный вариант решения с помощью нашего метода Обычной капчи (Normal Captcha).
Если виджет MTCaptcha отображает классическое текстовое или символьное изображение для ввода, вы можете сделать скриншот этого элемента с помощью Playwright или Selenium и отправить его на распознавание как обычную капчу. После получения текстового ответа его можно ввести в поле ввода капчи с помощью эмуляции нажатий клавиш.
Документация по методу Normal Captcha: https://2captcha.com/api-docs/normal-captcha
Частые ошибки и решения
| Ошибка / Проблема | Причина | Решение |
|---|---|---|
| ERROR_WRONG_USER_KEY | Неверный или пустой API-ключ. | Проверьте правильность копирования ключа из панели управления. |
| ERROR_ZERO_BALANCE | Недостаточно средств на балансе. | Пополните баланс аккаунта. |
| ERROR_CAPTCHA_UNSOLVABLE | Капча не может быть решена (например, истекло время или неверные параметры). | Убедитесь, что websiteKey и websiteURL скопированы точно. Не используйте устаревшие значения. |
| Токен не принимается формой | Неверное имя поля для внедрения или отсутствие вызова callback. | Проверьте исходный код страницы. Убедитесь, что вы внедряете токен в поле mt-captcha-response и при необходимости вызываете функцию проверки. |
Полезные ссылки
- Песочница для тестирования API: https://2captcha.com/setting#sandbox
- Документация API по MTCaptcha: https://2captcha.com/api-docs/mtcaptcha
- Документация API по Normal Captcha (альтернативный метод): https://2captcha.com/api-docs/normal-captcha
- Python SDK на GitHub: https://github.com/2captcha/2captcha-python
- Другие примеры обхода капч на сайтах: https://2captcha.com/h?category=sites