Airtable — это гибкая платформа базы данных, используемая для управления проектами, сбора данных и автоматизации рабочих процессов. Когда вашему рабочему процессу Airtable необходимо взаимодействовать со службами, защищенными CAPTCHA — отправка форм, обработка URL-адресов или автоматизация ввода данных —CaptchaAIможет решать CAPTCHA непосредственно из Airtable, используя расширения автоматизации и сценариев.
В этом руководстве показано, как настроить автоматизацию Airtable, которая запускает решение CAPTCHA через CaptchaAI при создании или обновлении новых записей.
Реальный сценарий
Вы отслеживаете целевые URL-адреса в таблице Airtable. Каждый URL-адрес имеет CAPTCHA, которую необходимо решить, прежде чем данные можно будет извлечь. При добавлении нового URL-адреса:
- Airtable Automation обнаруживает новую запись
- Скрипт передает параметры CAPTCHA в CaptchaAI.
- CaptchaAI возвращает решенный токен.
- Токен сохраняется обратно в запись Airtable.
Структура таблицы
Создайте таблицу Airtable под названием Задачи CAPTCHA со следующими полями:
| Имя поля | Тип | Цель |
|---|---|---|
| URL-адрес | URL-адрес | URL целевой страницы |
| Сайткей | Однострочный текст | reCAPTCHA ключ сайта |
| Статус | Одиночный выбор | в ожидании, решение, решено, не удалось |
| Токен | Длинный текст | Решенный токен CAPTCHA |
| Решено в | Дата/time | Временная метка решения |
| Ошибка | Однострочный текст | Сообщение об ошибке в случае неудачи |
Шаг 1. Создайте автоматизацию
В Airtable:
- Перейдите на вкладку Автоматизация.
- Нажмите Создать автоматизацию.
- Назовите его: «Решить CAPTCHA на новой записи».
Курок
Выберите Когда запись соответствует условиям:
- Таблица: Задачи CAPTCHA
- Условие: Статус «ожидает»
Это срабатывает каждый раз, когда для записи устанавливается статус «ожидающий» — охватывая как новые записи, так и повторные решения.
Шаг 2. Добавьте действие сценария.
Добавьте действие — Запустить скрипт:
// Airtable Automation Script — Solve CAPTCHA via CaptchaAI
// Input configuration (set in the left panel):
// - recordId: Record ID from trigger
// - sitekey: Sitekey field from trigger
// - pageurl: URL field from trigger
const config = input.config();
const recordId = config.recordId;
const sitekey = config.sitekey;
const pageurl = config.pageurl;
const API_KEY = 'YOUR_API_KEY'; // Use input.config() for security
// Update status to "solving"
const table = base.getTable('CAPTCHA Tasks');
await table.updateRecordAsync(recordId, {
'Status': { name: 'solving' },
});
try {
// Step 1: Submit task to CaptchaAI
const submitUrl = `https://ocr.captchaai.com/in.php?key=${API_KEY}&method=userrecaptcha&googlekey=${encodeURIComponent(sitekey)}&pageurl=${encodeURIComponent(pageurl)}&json=1`;
const submitResponse = await fetch(submitUrl);
const submitResult = await submitResponse.json();
if (submitResult.status !== 1) {
throw new Error(`Submit failed: ${submitResult.request}`);
}
const taskId = submitResult.request;
console.log(`Task submitted: ${taskId}`);
// Step 2: Poll for result (wait 15 seconds first)
await new Promise(resolve => setTimeout(resolve, 15000));
let token = null;
for (let i = 0; i < 20; i++) {
const pollUrl = `https://ocr.captchaai.com/res.php?key=${API_KEY}&action=get&id=${taskId}&json=1`;
const pollResponse = await fetch(pollUrl);
const pollResult = await pollResponse.json();
if (pollResult.status === 1) {
token = pollResult.request;
break;
}
if (pollResult.request !== 'CAPCHA_NOT_READY') {
throw new Error(`Solve failed: ${pollResult.request}`);
}
await new Promise(resolve => setTimeout(resolve, 5000));
}
if (!token) {
throw new Error('Polling timeout — CAPTCHA not solved in time');
}
// Step 3: Update record with solved token
await table.updateRecordAsync(recordId, {
'Status': { name: 'solved' },
'Token': token,
'Solved At': new Date().toISOString(),
'Error': '',
});
console.log(`CAPTCHA solved for record ${recordId}`);
} catch (error) {
// Update record with error
await table.updateRecordAsync(recordId, {
'Status': { name: 'failed' },
'Error': error.message,
});
console.error(`Failed: ${error.message}`);
}
Настройка входных данных сценария
На левой панели действия скрипта сопоставьте входные переменные:
recordId— идентификатор записи из шага триггера.sitekey— поле Sitekey из шага триггера.pageurl— поле URL из шага триггера.
Шаг 3. Пакетная обработка с помощью расширения сценариев
Для одновременной обработки большого количества записей используйте расширение сценариев Airtable (доступно на панели приложений):
// Batch CAPTCHA Solver — Airtable Scripting Extension
const API_KEY = 'YOUR_API_KEY';
const table = base.getTable('CAPTCHA Tasks');
// Get all pending records
const query = await table.selectRecordsAsync({
fields: ['URL', 'Sitekey', 'Status'],
});
const pendingRecords = query.records.filter(
r => r.getCellValueAsString('Status') === 'pending'
);
output.text(`Found ${pendingRecords.length} pending CAPTCHAs`);
for (const record of pendingRecords) {
const sitekey = record.getCellValueAsString('Sitekey');
const pageurl = record.getCellValueAsString('URL');
if (!sitekey || !pageurl) {
output.text(`Skipping ${record.id} — missing sitekey or URL`);
continue;
}
output.text(`Solving for: ${pageurl}`);
await table.updateRecordAsync(record.id, {
'Status': { name: 'solving' },
});
try {
// Submit
const submitResp = await fetch(
`https://ocr.captchaai.com/in.php?key=${API_KEY}&method=userrecaptcha&googlekey=${encodeURIComponent(sitekey)}&pageurl=${encodeURIComponent(pageurl)}&json=1`
);
const submitData = await submitResp.json();
if (submitData.status !== 1) throw new Error(submitData.request);
// Poll
await new Promise(r => setTimeout(r, 15000));
let token = null;
for (let i = 0; i < 20; i++) {
const pollResp = await fetch(
`https://ocr.captchaai.com/res.php?key=${API_KEY}&action=get&id=${submitData.request}&json=1`
);
const pollData = await pollResp.json();
if (pollData.status === 1) { token = pollData.request; break; }
if (pollData.request !== 'CAPCHA_NOT_READY') throw new Error(pollData.request);
await new Promise(r => setTimeout(r, 5000));
}
if (!token) throw new Error('Timeout');
await table.updateRecordAsync(record.id, {
'Status': { name: 'solved' },
'Token': token,
'Solved At': new Date().toISOString(),
});
output.text(`✓ Solved: ${pageurl}`);
} catch (e) {
await table.updateRecordAsync(record.id, {
'Status': { name: 'failed' },
'Error': e.message,
});
output.text(`✗ Failed: ${e.message}`);
}
}
output.text('Batch processing complete');
Поиск неисправностей
| Проблема | Причина | Исправить |
Следующие шаги
- CaptchaAI Quickstart: ваше первое решение CAPTCHA за 5 минут
- Как решить reCAPTCHA v2 через API: пошаговое руководство
- Как решить Cloudflare Turnstile через API
- Как решить GeeTest v3 с помощью API