Tập lệnh Shell với cURL là cách linh hoạt nhất, không phụ thuộc để tương tác với API. Mọi hệ thống Linux/macOS đều được cài đặt Bash và cURL. Khi các công việc định kỳ, đường dẫn CI/CD hoặc tập lệnh giám sát của bạn gặp phải CAPTCHA, API HTTP của CaptchaAI sẽ hoạt động trực tiếp với các lệnh cURL.
Hướng dẫn này đề cập đến cách giải reCAPTCHA v2/v3, Cloudflare Turnstile và giải CAPTCHA hình ảnh bằng cách sử dụng Bash thuần túy - không cần Python, Node.js hoặc thời gian chạy khác.
Tại sao Bash + cURL để giải CAPTCHA
- Không phụ thuộc — Bash và cURL đi kèm với mọi hệ thống Linux/macOS
- Nhẹ nhàng — không cần thời gian chạy, không cần trình quản lý gói, không cần bước cài đặt
- Thân thiện với Cron — lên lịch các tác vụ phụ thuộc vào CAPTCHA bằng cron tiêu chuẩn
- CI/CD đã sẵn sàng — hoạt động trong Docker, GitHub Actions, Jenkins, GitLab CI
- Sẵn sàng cho đường ống - giải CAPTCHA chuỗi bằng
jq,grep,awkvà các công cụ khác
Điều kiện tiên quyết
- Bash 4.0+
- cURL (được cài đặt mặc định trên Linux/macOS)
jqđể phân tích cú pháp JSON:apt install jqhoặcbrew install jq- Khóa API CaptchaAI (lấy một cái ở đây)
Chức năng cốt lõi
Gửi nhiệm vụ
#!/bin/bash
CAPTCHAAI_URL="https://ocr.captchaai.com"
submit_task() {
local api_key="$1"
shift
local params=("$@")
local response
response=$(curl -s -X POST "${CAPTCHAAI_URL}/in.php" \
-d "key=${api_key}" \
-d "json=1" \
"${params[@]}")
local status
status=$(echo "$response" | jq -r '.status')
local request
request=$(echo "$response" | jq -r '.request')
if [ "$status" != "1" ]; then
echo "ERROR: Submit failed: $request" >&2
return 1
fi
echo "$request"
}
Kết quả thăm dò ý kiến
poll_result() {
local api_key="$1"
local task_id="$2"
local max_wait="${3:-300}"
local interval="${4:-5}"
local elapsed=0
while [ "$elapsed" -lt "$max_wait" ]; do
sleep "$interval"
elapsed=$((elapsed + interval))
local response
response=$(curl -s "${CAPTCHAAI_URL}/res.php?key=${api_key}&action=get&id=${task_id}&json=1")
local status
status=$(echo "$response" | jq -r '.status')
local request
request=$(echo "$response" | jq -r '.request')
if [ "$request" = "CAPCHA_NOT_READY" ]; then
echo "Waiting... (${elapsed}s/${max_wait}s)" >&2
continue
fi
if [ "$status" != "1" ]; then
echo "ERROR: Solve failed: $request" >&2
return 1
fi
echo "$request"
return 0
done
echo "ERROR: Timeout after ${max_wait}s" >&2
return 1
}
Giải reCAPTCHA v2
solve_recaptcha_v2() {
local api_key="$1"
local site_url="$2"
local sitekey="$3"
echo "Submitting reCAPTCHA v2..." >&2
local task_id
task_id=$(submit_task "$api_key" \
-d "method=userrecaptcha" \
-d "googlekey=${sitekey}" \
-d "pageurl=${site_url}")
if [ $? -ne 0 ]; then return 1; fi
echo "Task ID: $task_id" >&2
echo "Polling for solution..." >&2
local token
token=$(poll_result "$api_key" "$task_id")
if [ $? -ne 0 ]; then return 1; fi
echo "$token"
}
# Usage
API_KEY="YOUR_API_KEY"
TOKEN=$(solve_recaptcha_v2 "$API_KEY" \
"https://staging.example.com/qa-login" \
"6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-")
echo "Token: ${TOKEN:0:50}..."
Giải Cloudflare Turnstile
solve_turnstile() {
local api_key="$1"
local site_url="$2"
local sitekey="$3"
local task_id
task_id=$(submit_task "$api_key" \
-d "method=turnstile" \
-d "key=${sitekey}" \
-d "pageurl=${site_url}")
if [ $? -ne 0 ]; then return 1; fi
poll_result "$api_key" "$task_id"
}
# Usage
TOKEN=$(solve_turnstile "$API_KEY" \
"https://example.com/form" \
"0x4AAAAAAAB5...")
Giải reCAPTCHA v3
solve_recaptcha_v3() {
local api_key="$1"
local site_url="$2"
local sitekey="$3"
local action="${4:-verify}"
local min_score="${5:-0.7}"
local task_id
task_id=$(submit_task "$api_key" \
-d "method=userrecaptcha" \
-d "googlekey=${sitekey}" \
-d "pageurl=${site_url}" \
-d "version=v3" \
-d "action=${action}" \
-d "min_score=${min_score}")
if [ $? -ne 0 ]; then return 1; fi
poll_result "$api_key" "$task_id"
}
Giải CAPTCHA hình ảnh
solve_image_captcha() {
local api_key="$1"
local image_path="$2"
if [ ! -f "$image_path" ]; then
echo "ERROR: File not found: $image_path" >&2
return 1
fi
local base64_data
base64_data=$(base64 -w 0 "$image_path" 2>/dev/null || base64 "$image_path")
local task_id
task_id=$(submit_task "$api_key" \
-d "method=base64" \
--data-urlencode "body=${base64_data}")
if [ $? -ne 0 ]; then return 1; fi
poll_result "$api_key" "$task_id"
}
# From URL
solve_image_from_url() {
local api_key="$1"
local image_url="$2"
local tmp_file
tmp_file=$(mktemp /tmp/captcha_XXXXXX.png)
curl -s -o "$tmp_file" "$image_url"
local result
result=$(solve_image_captcha "$api_key" "$tmp_file")
rm -f "$tmp_file"
echo "$result"
}
# Usage
TEXT=$(solve_image_captcha "$API_KEY" "captcha.png")
echo "CAPTCHA text: $TEXT"
Tập lệnh giải hoàn chỉnh
Lưu dưới dạng captchaai.sh và lấy nguồn từ các tập lệnh khác:
#!/bin/bash
# CaptchaAI Solver Library
# Source this file: source ./captchaai.sh
CAPTCHAAI_URL="https://ocr.captchaai.com"
CAPTCHAAI_POLL_INTERVAL=5
CAPTCHAAI_MAX_WAIT=300
captchaai_submit() {
local api_key="$1"; shift
local response
response=$(curl -s -X POST "${CAPTCHAAI_URL}/in.php" \
-d "key=${api_key}" -d "json=1" "$@")
local status=$(echo "$response" | jq -r '.status')
local request=$(echo "$response" | jq -r '.request')
[ "$status" = "1" ] && echo "$request" || { echo "Submit: $request" >&2; return 1; }
}
captchaai_poll() {
local api_key="$1" task_id="$2" elapsed=0
while [ "$elapsed" -lt "$CAPTCHAAI_MAX_WAIT" ]; do
sleep "$CAPTCHAAI_POLL_INTERVAL"
elapsed=$((elapsed + CAPTCHAAI_POLL_INTERVAL))
local resp=$(curl -s "${CAPTCHAAI_URL}/res.php?key=${api_key}&action=get&id=${task_id}&json=1")
local req=$(echo "$resp" | jq -r '.request')
local st=$(echo "$resp" | jq -r '.status')
[ "$req" = "CAPCHA_NOT_READY" ] && continue
[ "$st" = "1" ] && { echo "$req"; return 0; }
echo "Solve: $req" >&2; return 1
done
echo "Timeout" >&2; return 1
}
captchaai_balance() {
local api_key="$1"
curl -s "${CAPTCHAAI_URL}/res.php?key=${api_key}&action=getbalance&json=1" | jq -r '.request'
}
captchaai_recaptcha_v2() {
local key="$1" url="$2" sk="$3"
local tid=$(captchaai_submit "$key" -d "method=userrecaptcha" -d "googlekey=$sk" -d "pageurl=$url") || return 1
captchaai_poll "$key" "$tid"
}
captchaai_turnstile() {
local key="$1" url="$2" sk="$3"
local tid=$(captchaai_submit "$key" -d "method=turnstile" -d "key=$sk" -d "pageurl=$url") || return 1
captchaai_poll "$key" "$tid"
}
captchaai_image() {
local key="$1" path="$2"
local b64=$(base64 -w 0 "$path" 2>/dev/null || base64 "$path")
local tid=$(captchaai_submit "$key" -d "method=base64" --data-urlencode "body=$b64") || return 1
captchaai_poll "$key" "$tid"
}
Sử dụng Thư viện
#!/bin/bash
source ./captchaai.sh
API_KEY="YOUR_API_KEY"
# Check balance
echo "Balance: $(captchaai_balance "$API_KEY")"
# Solve reCAPTCHA v2
TOKEN=$(captchaai_recaptcha_v2 "$API_KEY" \
"https://staging.example.com/qa-login" \
"6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-")
echo "Token: ${TOKEN:0:50}..."
Gửi biểu mẫu với mã thông báo đã giải quyết
submit_form_with_token() {
local url="$1"
local token="$2"
shift 2
curl -s -X POST "$url" \
-d "g-recaptcha-response=${token}" \
"$@"
}
# Usage: solve then submit
TOKEN=$(captchaai_recaptcha_v2 "$API_KEY" \
"https://staging.example.com/qa-login" "SITEKEY")
RESPONSE=$(submit_form_with_token "https://staging.example.com/qa-login" \
"$TOKEN" \
-d "username=user@example.com" \
-d "password=password")
echo "Response: $RESPONSE"
Giải quyết song song với công việc nền
#!/bin/bash
source ./captchaai.sh
API_KEY="YOUR_API_KEY"
RESULTS_DIR=$(mktemp -d)
# Define tasks
declare -A TASKS
TASKS["site-a"]="https://site-a.com|SITEKEY_A"
TASKS["site-b"]="https://site-b.com|SITEKEY_B"
TASKS["site-c"]="https://site-c.com|SITEKEY_C"
# Launch parallel solves
pids=()
for name in "${!TASKS[@]}"; do
IFS='|' read -r url sitekey <<< "${TASKS[$name]}"
(
token=$(captchaai_recaptcha_v2 "$API_KEY" "$url" "$sitekey" 2>/dev/null)
if [ $? -eq 0 ]; then
echo "$token" > "${RESULTS_DIR}/${name}.token"
else
echo "FAILED" > "${RESULTS_DIR}/${name}.token"
fi
) &
pids+=($!)
done
# Wait for all
for pid in "${pids[@]}"; do
wait "$pid"
done
# Collect results
echo "=== Results ==="
for name in "${!TASKS[@]}"; do
token=$(cat "${RESULTS_DIR}/${name}.token")
if [ "$token" = "FAILED" ]; then
echo "$name: FAILED"
else
echo "$name: ${token:0:50}..."
fi
done
rm -rf "$RESULTS_DIR"
Thử lại với thời gian chờ theo cấp số nhân
solve_with_retry() {
local api_key="$1"
local solve_cmd="$2"
shift 2
local max_retries="${1:-3}"
local retryable_errors=("ERROR_NO_SLOT_AVAILABLE" "ERROR_CAPTCHA_UNSOLVABLE")
local attempt=0
while [ "$attempt" -le "$max_retries" ]; do
if [ "$attempt" -gt 0 ]; then
local delay=$((2 ** attempt + RANDOM % 3))
echo "Retry $attempt/$max_retries after ${delay}s..." >&2
sleep "$delay"
fi
local result
result=$($solve_cmd "$api_key" "${@:2}")
if [ $? -eq 0 ]; then
echo "$result"
return 0
fi
# Check if error is retryable
local is_retryable=0
for err in "${retryable_errors[@]}"; do
if echo "$result" | grep -q "$err"; then
is_retryable=1
break
fi
done
if [ "$is_retryable" -eq 0 ]; then
echo "$result"
return 1
fi
attempt=$((attempt + 1))
done
echo "Max retries exceeded" >&2
return 1
}
Tích hợp công việc định kỳ
# Edit crontab: crontab -e
# Run daily at 8 AM
0 8 * * * /path/to/captcha-automation.sh >> /var/log/captcha.log 2>&1
Tập lệnh cron ví dụ:
#!/bin/bash
source /path/to/captchaai.sh
API_KEY="YOUR_API_KEY"
LOG_FILE="/var/log/captcha-$(date +%Y%m%d).log"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"; }
# Check balance first
BALANCE=$(captchaai_balance "$API_KEY")
log "Balance: $BALANCE"
if (( $(echo "$BALANCE < 1.0" | bc -l) )); then
log "WARNING: Low balance!"
exit 1
fi
# Solve and process
TOKEN=$(captchaai_recaptcha_v2 "$API_KEY" \
"https://portal.example.com" "SITEKEY")
if [ $? -eq 0 ]; then
log "Solved successfully"
# Submit form, download data, etc.
curl -s "https://portal.example.com/data" \
-d "g-recaptcha-response=$TOKEN" \
-o "/data/export-$(date +%Y%m%d).csv"
log "Data exported"
else
log "ERROR: Failed to solve CAPTCHA"
exit 1
fi
Tích hợp Docker
FROM alpine:3.19
RUN apk add --no-cache bash curl jq
COPY captchaai.sh /usr/local/lib/captchaai.sh
COPY automation.sh /app/automation.sh
RUN chmod +x /app/automation.sh
CMD ["/app/automation.sh"]
Khắc phục sự cố
| Lỗi | nguyên nhân | sửa chữa |
|---|---|---|
ERROR_WRONG_USER_KEY |
Khóa API không hợp lệ | Xác minh khóa tại bảng điều khiển |
ERROR_ZERO_BALANCE |
Không có tiền | Nạp tiền vào tài khoản |
curl: (60) SSL certificate |
Thiếu gói CA | Thêm --cacert /path/to/ca-bundle.crt hoặc -k để thử nghiệm |
jq: command not found |
jq chưa được cài đặt | apt install jq hoặc brew install jq |
base64: invalid option -- 'w' |
Cú pháp macOS base64 | Sử dụng base64 file thay vì base64 -w 0 file |
| Phản hồi trống | Sự cố mạng | Thêm cờ -v để cuộn tròn để gỡ lỗi |
Câu hỏi thường gặp
Tôi có cần jq không?
Để phân tích cú pháp JSON, có. Ngoài ra, bạn có thể sử dụng grep và sed để trích xuất các giá trị, nhưng jq đáng tin cậy hơn nhiều.
Cái này có hoạt động trên macOS không?
Có, nhưng lưu ý rằng macOS sử dụng phiên bản BSD của base64 và các công cụ khác. Tập lệnh xử lý cả cú pháp base64 của Linux và macOS.
Tôi có thể sử dụng cái này trong vùng chứa Docker không?
Vâng. Alpine Linux với bash, curl và jq tạo ra một vùng chứa tối thiểu (~10 MB) để tự động hóa CAPTCHA.
Làm cách nào để lưu trữ khóa API một cách an toàn?
Sử dụng các biến môi trường: export CAPTCHAAI_KEY="..." và tham chiếu $CAPTCHAAI_KEY trong tập lệnh. Không bao giờ mã hóa khóa cứng trong các tệp được kiểm soát theo phiên bản.
Hướng dẫn liên quan
- PowerShell + CaptchaAI Tự động hóa Windows
- Giải CAPTCHA bằng Perl
- Tài liệu API CaptchaAI
Giải CAPTCHA từ dòng lệnh —lấy khóa API của bạnvà tự động hóa với Bash.