Генерация заголовков Kasada с помощью cURL

Автор: solvethree3 мин на чтение

Создайте KasadaTask, дождитесь ready, затем отправьте весь объект solution.headers с возвращёнными идентификационными данными браузера через тот же прокси. Отдельный режим Kasada сейчас поддерживает HTTPS-адреса на www.ticketmaster.com.

На этой странице

Создайте задачу, опрашивайте её и отправьте результат с помощью cURL

Для скрипта нужны Bash, cURL 7.76 или новее, jq и openssl. Укажите в SOLVETHREE_API_KEY API-ключ рабочего пространства, а в SOLVETHREE_PROXY — URL HTTP- или HTTPS-прокси. Храните API-ключ на сервере и не включайте трассировку команд оболочки.

В этом примере на всех этапах используется один прокси. Запрос Kasada требует type, url и ровно одно из полей proxy или proxyCandidates; он не должен содержать поля reCAPTCHA, такие как site или action, поле session или пользовательские поля идентификации браузера. См. контракт запроса Kasada.

KASADA · создание, опрос и применение результата
#!/usr/bin/env bash
set -euo pipefail
: "${SOLVETHREE_API_KEY:?Set the API key}" "${SOLVETHREE_PROXY:?Set the proxy}"
# Requires bash, curl, jq and openssl. Do not enable shell tracing.
work=$(mktemp -d)
chmod 700 "$work"
trap 'rm -rf "$work"' EXIT
request_id=$(openssl rand -hex 16)
printf 'Recovery requestId=%s\n' "$request_id"
printf 'Authorization: Bearer %s\n' "$SOLVETHREE_API_KEY" > "$work/auth"
jq -n --arg proxy "$SOLVETHREE_PROXY" --arg id "$request_id" '{"type":"KasadaTask","url":"https://www.ticketmaster.com/","proxy":$proxy,"requestId":$id}' > "$work/input.json"
api='https://api.solvethree.com/v1'
curl --fail-with-body --silent --show-error --max-time 30 \
  --header @"$work/auth" --header 'Content-Type: application/json' \
  --data-binary @"$work/input.json" --output "$work/result.json" "$api/tasks?waitMs=0"
task_id=$(jq -er '.id' "$work/result.json")
encoded_id=$(jq -nr --arg id "$task_id" '$id|@uri')
printf 'Recovery taskId=%s\n' "$task_id"
deadline=$((SECONDS + 180))
while [[ $(jq -r '.status' "$work/result.json") =~ ^(pending|solving)$ ]]; do
  remaining=$((deadline - SECONDS))
  (( remaining > 0 )) || { echo 'Local deadline reached; resume the saved task ID' >&2; exit 1; }
  timeout=$((remaining < 25 ? remaining : 25))
  curl --fail-with-body --silent --show-error --max-time "$timeout" \
    --header @"$work/auth" --output "$work/result.json" "$api/tasks/$encoded_id?waitMs=15000"
  [[ $(jq -r '.status' "$work/result.json") =~ ^(pending|solving)$ ]] && sleep 1 || true
done
[[ $(jq -r '.status' "$work/result.json") == ready ]] || { echo 'Solver task failed' >&2; exit 1; }
user_agent=$(jq -er '.solution.userAgent' "$work/result.json")
client_hints=$(jq -er '.solution.secChUa' "$work/result.json")
jq -r '.solution.headers | to_entries[] | "\(.key): \(.value)"' "$work/result.json" > "$work/target-headers"
curl --silent --show-error --max-time 30 --proxy "$SOLVETHREE_PROXY" \
  --header @"$work/target-headers" --user-agent "$user_agent" \
  --header "sec-ch-ua: $client_hints" --output "$work/target-response" \
  --write-out 'Target HTTP %{http_code}\n' 'https://www.ticketmaster.com/'
# Inspect the application's response before treating the operation as successful.
# Replace the example target path with the actual supported workflow URL.

Замените пример целевого URL и в теле задачи, и в финальном вызове cURL на нужный URL поддерживаемого сценария. Не получайте решение для одного URL, чтобы затем отправить результат на несвязанный адрес.

Скрипт аутентифицируется с помощью заголовка Bearer, создаёт одну задачу и опрашивает только возвращённый для неё ID. Тайм-аут запроса создания составляет 30 секунд; опрос использует локальный лимит в 180 секунд и ограниченные по времени GET-запросы. Это ограничения скрипта, а не гарантии времени решения. Автоматические повторы и переходы по перенаправлениям не включены.

Применяйте весь объект заголовков

pending и solving означают, что опрос нужно продолжать. Только ready содержит пригодное для использования решение. Скрипт читает исходный объект solution.headers с помощью jq и преобразует каждую запись в строку файла заголовков; он не выбирает отдельный заголовок и не использует ID задачи в качестве решения.

Финальный запрос загружает этот файл заголовков, задаёт solution.userAgent и solution.secChUa и использует исходный прокси. Используйте эти значения вместе, не подменяя их привычными заголовками браузера.

Ответы API, сгенерированные заголовки и ответ целевого сервера остаются в закрытом временном каталоге, а не выводятся на экран. Не включайте их в обычные журналы и не включайте трассировку команд оболочки.

Восстановите задачу вместо создания новой

Сохраните выведенные идентификаторы для восстановления. Повторный запуск скрипта генерирует новый requestId; это не попытка восстановления. Чтобы восстановить результат создания, повторно используйте сохранённый ID запроса с точно такими же исходными входными данными задачи. Скрипт удаляет входной файл при выходе, поэтому храните эти данные безопасно, если понадобится восстановить запрос.

Тайм-аут POST-запроса наступает до получения ID задачи.

Тайм-аут соединения не доказывает, что создать задачу не удалось.

Попробуйте: Отправьте тот же запрос задачи с сохранённым requestId. Идентичные входные данные позволяют восстановить существующую задачу; изменение данных при повторном использовании этого ID вызывает конфликт.

Истекает локальный лимит времени опроса.

Используйте выведенный ID задачи, чтобы проверить, остаётся ли существующая задача в состоянии pending или solving.

Попробуйте: Возобновите GET-опрос для этого ID с новым конечным лимитом времени. Не создавайте замену лишь потому, что локальное ожидание закончилось.

Запрос API возвращает неуспешный HTTP-ответ.

Вызовы API используют --fail-with-body, поэтому cURL завершает работу до того, как скрипт прочитает данные успешного ответа.

Попробуйте: Для диагностики добавьте обработчик HTTP-ошибок, который до очистки проверяет сохранённое тело ответа без его публичного вывода. Исправьте указанную проблему запроса, а не повторяйте вслепую неизменные входные данные.

Задача переходит в статус failed.

Пример выводит общее сообщение об ошибке; ответ также содержит errorCode и error.

Попробуйте: Проверьте эти поля в ветке обработки сбоя до очистки, затем прекратите опрос этой задачи. На основании указанной причины решите, что изменить. За неудачные решения средства возвращаются.

Запустите первую задачу.

Начните с $5 на балансе рабочего пространства.

Создать рабочее пространство
Генерация заголовков Kasada с помощью cURL · solvethree