Логотип «2Captcha»Перейти на главную страницу
Туториалы по обходу капчи

Эта статья была полезной?

Как обойти 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 являются статическими для конкретной страницы и легко извлекаются из исходного кода.

  1. Откройте сайт https://www.checkinhoudingsplicht.be/ в браузере.
  2. Нажмите F12, чтобы открыть Инструменты разработчика (DevTools), и перейдите на вкладку Элементы (Elements).
  3. Нажмите Ctrl+F (или Cmd+F) и выполните поиск по фразе mt-captcha или data-sitekey.
  4. Вы найдете div-элемент, похожий на этот:
  5. Значение атрибута data-sitekey (в данном примере MTPublic-QPs1BHRjl) является вашим websiteKey.
  6. Скопируйте полный URL из адресной строки браузера. Это будет ваш websiteURL.

Примеры кода

Python + requests (API v2)

Пример отправки задачи и опроса результата с использованием библиотеки requests через эндпоинты API v2.

python Copy
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 Copy
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 и при необходимости вызываете функцию проверки.

Полезные ссылки