Skip to content

Commit 1a60962

Browse files
committed
Add hCaptcha solving examples for multiple languages using CaptchaAI API
- Created Node.js example with package.json and solve.js - Added PHP example with composer.json and solve.php - Included Python example with requirements.txt and solve.py - Introduced Ruby example with Gemfile and solve.rb - Implemented Rust example with Cargo.toml and main.rs
1 parent 387e573 commit 1a60962

42 files changed

Lines changed: 4518 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ CaptchaAI-Examples/
6464
| [how-to-solve-bls-captcha-step-by-step](articles/how-to-solve-bls-captcha-step-by-step/) | BLS CAPTCHA | Python, Node.js, PHP, Go, Java, C#, Ruby, Rust, Kotlin, Bash | [Blog](https://blog.captchaai.com/how-to-solve-bls-captcha-step-by-step) |
6565
| [image-captcha-solving-using-api](articles/image-captcha-solving-using-api/) | Image/OCR CAPTCHA | Python, Node.js, PHP, Go, Java, C#, Ruby, Rust, Kotlin, Bash | [Blog](https://blog.captchaai.com/image-captcha-solving-using-api) |
6666
| [how-to-solve-grid-image-captcha-automatically](articles/how-to-solve-grid-image-captcha-automatically/) | Grid Image CAPTCHA | Python, Node.js, PHP, Go, Java, C#, Ruby, Rust, Kotlin, Bash | [Blog](https://blog.captchaai.com/how-to-solve-grid-image-captcha-automatically) |
67+
| [how-to-solve-hcaptcha-using-api](articles/how-to-solve-hcaptcha-using-api/) | hCaptcha | Python, Node.js, PHP, Go, Java, C#, Ruby, Rust, Kotlin, Bash | [Blog](https://blog.captchaai.com/how-to-solve-hcaptcha-using-api) |
68+
| [how-to-solve-geetest-v4-using-api](articles/how-to-solve-geetest-v4-using-api/) | GeeTest v4 | Python, Node.js, PHP, Go, Java, C#, Ruby, Rust, Kotlin, Bash | [Blog](https://blog.captchaai.com/how-to-solve-geetest-v4-using-api) |
6769

6870
## How each example works
6971

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# CaptchaAI API credentials
2+
# Get your API key from https://captchaai.com/dashboard (32 characters)
3+
CAPTCHAAI_API_KEY=YOUR_API_KEY
4+
5+
# Target page configuration
6+
# The gt value is the captcha_id — find it in the page source or GeeTest v4 initialization call
7+
CAPTCHA_GT=YOUR_CAPTCHA_ID
8+
# Full URL of the page where the GeeTest v4 widget loads
9+
CAPTCHA_PAGEURL=https://example.com
10+
11+
# Polling configuration (optional)
12+
POLL_INTERVAL=5
13+
MAX_TIMEOUT=120
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
.env
2+
__pycache__/
3+
*.pyc
4+
node_modules/
5+
vendor/
6+
composer.lock
7+
package-lock.json
8+
.DS_Store
9+
Thumbs.db
10+
# Go
11+
go.sum
12+
# Java
13+
*.class
14+
# C#
15+
bin/
16+
obj/
17+
# Ruby
18+
Gemfile.lock
19+
# Rust
20+
target/
21+
Cargo.lock
22+
# Kotlin
23+
*.jar
24+
# Bash
25+
*.log
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# GeeTest v4 — CaptchaAI Example Pack
2+
3+
Full working example for solving GeeTest v4 using the CaptchaAI API.
4+
5+
**Languages:** Python, Node.js, PHP, Go, Java, C#, Ruby, Rust, Kotlin, Bash
6+
7+
## Related article
8+
9+
This example accompanies the blog article:
10+
**[How to Solve GeeTest v4 Using API](https://blog.captchaai.com/how-to-solve-geetest-v4-using-api)**
11+
12+
## Prerequisites
13+
14+
- A CaptchaAI account with API key ([get one here](https://captchaai.com))
15+
- A target page with GeeTest v4 for testing
16+
- One or more of: Python 3.8+, Node.js 16+, PHP 8.0+, Go 1.21+, Java 11+, .NET 8+, Ruby 3.0+, Rust 1.70+, Kotlin 1.9+, or Bash with curl and jq
17+
18+
## GeeTest v4 parameters
19+
20+
| Parameter | Required | Description |
21+
|-----------|----------|-------------|
22+
| `gt` | Yes | The `captcha_id` — GeeTest v4 identifier for the site (find in page source or GeeTest v4 init call) |
23+
| `version` | Yes | Must be `4` for GeeTest v4 |
24+
| `pageurl` | Yes | Full URL of the page with the GeeTest v4 widget |
25+
26+
> **Note:** Unlike GeeTest v3, GeeTest v4 does **not** require a `challenge` parameter.
27+
28+
## Response
29+
30+
The API returns five values that must be submitted together to the site's GeeTest v4 verification endpoint:
31+
32+
- `captcha_id` — the GeeTest captcha identifier
33+
- `lot_number` — the lot number for this solve
34+
- `pass_token` — the pass token
35+
- `gen_time` — the generation timestamp
36+
- `captcha_output` — the captcha output value
37+
38+
## Setup
39+
40+
1. Clone the repository:
41+
```bash
42+
git clone https://github.com/CaptchaAI/CaptchaAI-Examples.git
43+
cd CaptchaAI-Examples/articles/how-to-solve-geetest-v4-using-api
44+
```
45+
46+
2. Copy the environment file and add your credentials:
47+
```bash
48+
cp .env.example .env
49+
```
50+
51+
3. Edit `.env` with your API key and target page details.
52+
53+
4. Follow the language-specific setup below.
54+
55+
### Python
56+
57+
```bash
58+
cd python
59+
pip install -r requirements.txt
60+
python solve.py
61+
```
62+
63+
### Node.js
64+
65+
```bash
66+
cd node
67+
npm install
68+
node solve.js
69+
```
70+
71+
### PHP
72+
73+
```bash
74+
cd php
75+
composer install
76+
php solve.php
77+
```
78+
79+
### Go
80+
81+
```bash
82+
cd go
83+
go run solve.go
84+
```
85+
86+
### Java
87+
88+
```bash
89+
cd java
90+
javac Solve.java
91+
java Solve
92+
```
93+
94+
### C#
95+
96+
```bash
97+
cd csharp
98+
dotnet run
99+
```
100+
101+
### Ruby
102+
103+
```bash
104+
cd ruby
105+
ruby solve.rb
106+
```
107+
108+
### Rust
109+
110+
```bash
111+
cd rust
112+
cargo run
113+
```
114+
115+
### Kotlin
116+
117+
```bash
118+
cd kotlin
119+
kotlinc solve.kt -include-runtime -d solve.jar
120+
java -jar solve.jar
121+
```
122+
123+
### Bash
124+
125+
```bash
126+
cd bash
127+
chmod +x solve.sh
128+
bash solve.sh
129+
```
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
#!/usr/bin/env bash
2+
# Solve GeeTest v4 using the CaptchaAI API.
3+
#
4+
# Usage:
5+
# chmod +x solve.sh
6+
# bash solve.sh
7+
8+
set -euo pipefail
9+
10+
SUBMIT_URL="https://ocr.captchaai.com/in.php"
11+
RESULT_URL="https://ocr.captchaai.com/res.php"
12+
13+
# Load .env
14+
ENV_FILE="$(dirname "$0")/../.env"
15+
if [[ -f "$ENV_FILE" ]]; then
16+
set -a
17+
# shellcheck disable=SC1090
18+
source "$ENV_FILE"
19+
set +a
20+
fi
21+
22+
API_KEY="${CAPTCHAAI_API_KEY:-}"
23+
GT="${CAPTCHA_GT:-}"
24+
PAGEURL="${CAPTCHA_PAGEURL:-}"
25+
POLL_INTERVAL="${POLL_INTERVAL:-5}"
26+
MAX_TIMEOUT="${MAX_TIMEOUT:-120}"
27+
28+
# Validate
29+
if [[ -z "$API_KEY" || "$API_KEY" == "YOUR_API_KEY" ]]; then
30+
echo "[!] ERROR: CAPTCHAAI_API_KEY is not set."
31+
echo " Copy .env.example to .env and add your real API key."
32+
exit 1
33+
fi
34+
if [[ -z "$GT" || "$GT" == "YOUR_CAPTCHA_ID" ]]; then
35+
echo "[!] ERROR: CAPTCHA_GT is not set."
36+
echo " Find the captcha_id in the page source or GeeTest v4 initialization call."
37+
exit 1
38+
fi
39+
if [[ -z "$PAGEURL" || "$PAGEURL" == "https://example.com" ]]; then
40+
echo "[!] WARNING: CAPTCHA_PAGEURL may not be set correctly."
41+
echo " Make sure it points to the actual target page."
42+
fi
43+
44+
# JSON helpers
45+
json_str() {
46+
local json="$1" key="$2"
47+
echo "$json" | grep -oP "\"${key}\":\s*\"\\K[^\"]*" || echo ""
48+
}
49+
json_int() {
50+
local json="$1" key="$2"
51+
echo "$json" | grep -oP "\"${key}\":\s*\\K[0-9]+" || echo "0"
52+
}
53+
54+
# Error handler
55+
handle_error() {
56+
local error="$1"
57+
case "$error" in
58+
ERROR_WRONG_USER_KEY|ERROR_KEY_DOES_NOT_EXIST|IP_BANNED)
59+
echo "[!] Authentication error: $error"
60+
echo " Check your API key at https://captchaai.com/dashboard"
61+
;;
62+
ERROR_ZERO_BALANCE)
63+
echo "[!] Balance error: $error"
64+
echo " Top up your account at https://captchaai.com"
65+
;;
66+
ERROR_PAGEURL|ERROR_WRONG_GOOGLEKEY|ERROR_BAD_PARAMETERS|ERROR_BAD_TOKEN_OR_PAGEURL)
67+
echo "[!] Input error: $error"
68+
echo " Verify your gt (captcha_id) and page URL are correct."
69+
;;
70+
ERROR_BAD_PROXY|ERROR_PROXY_CONNECTION_FAILED)
71+
echo "[!] Proxy error: $error"
72+
echo " Check your proxy configuration or try a different proxy."
73+
;;
74+
*)
75+
echo "[!] Submission failed: $error"
76+
;;
77+
esac
78+
}
79+
80+
# Submit task
81+
echo "[*] Submitting GeeTest v4 task..."
82+
ENCODED_KEY=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$API_KEY'))" 2>/dev/null || echo "$API_KEY")
83+
ENCODED_GT=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$GT'))" 2>/dev/null || echo "$GT")
84+
ENCODED_PAGEURL=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$PAGEURL'))" 2>/dev/null || echo "$PAGEURL")
85+
86+
SUBMIT_QUERY="key=${ENCODED_KEY}&method=geetest&gt=${ENCODED_GT}&pageurl=${ENCODED_PAGEURL}&version=4&json=1"
87+
88+
SUBMIT_RESP=$(curl -sS --max-time 30 "${SUBMIT_URL}?${SUBMIT_QUERY}")
89+
90+
if [[ -z "$SUBMIT_RESP" ]]; then
91+
echo "[!] Network error during submission."
92+
exit 1
93+
fi
94+
95+
SUBMIT_STATUS=$(json_int "$SUBMIT_RESP" "status")
96+
SUBMIT_REQUEST=$(json_str "$SUBMIT_RESP" "request")
97+
98+
if [[ "$SUBMIT_STATUS" -ne 1 ]]; then
99+
handle_error "$SUBMIT_REQUEST"
100+
exit 1
101+
fi
102+
103+
TASK_ID="$SUBMIT_REQUEST"
104+
echo "[+] Task submitted. ID: $TASK_ID"
105+
106+
# Poll for result
107+
echo "[*] Waiting 15s before first poll..."
108+
sleep 15
109+
110+
ELAPSED=15
111+
ATTEMPT=0
112+
BACKOFF="$POLL_INTERVAL"
113+
114+
while [[ "$ELAPSED" -lt "$MAX_TIMEOUT" ]]; do
115+
ATTEMPT=$((ATTEMPT + 1))
116+
echo "[*] Polling for result (attempt $ATTEMPT)..."
117+
118+
POLL_RESP=$(curl -sS --max-time 30 \
119+
"${RESULT_URL}?key=${ENCODED_KEY}&action=get&id=${TASK_ID}&json=1" 2>/dev/null || echo "")
120+
121+
if [[ -z "$POLL_RESP" ]]; then
122+
echo "[!] Network error during polling."
123+
sleep "$BACKOFF"
124+
ELAPSED=$((ELAPSED + BACKOFF))
125+
BACKOFF=$((BACKOFF * 2))
126+
[[ "$BACKOFF" -gt 30 ]] && BACKOFF=30
127+
continue
128+
fi
129+
130+
STATUS=$(json_int "$POLL_RESP" "status")
131+
132+
if [[ "$STATUS" -eq 1 ]]; then
133+
# Extract the 5 GeeTest v4 values from the response
134+
CAPTCHA_ID_VAL=$(echo "$POLL_RESP" | grep -oP '"captcha_id"\s*:\s*"\\K[^"]*' || echo "")
135+
LOT_NUMBER=$(echo "$POLL_RESP" | grep -oP '"lot_number"\s*:\s*"\\K[^"]*' || echo "")
136+
PASS_TOKEN=$(echo "$POLL_RESP" | grep -oP '"pass_token"\s*:\s*"\\K[^"]*' || echo "")
137+
GEN_TIME=$(echo "$POLL_RESP" | grep -oP '"gen_time"\s*:\s*"\\K[^"]*' || echo "")
138+
CAPTCHA_OUTPUT=$(echo "$POLL_RESP" | grep -oP '"captcha_output"\s*:\s*"\\K[^"]*' || echo "")
139+
140+
# If values are empty, the request might be a JSON string — try extracting from unescaped content
141+
if [[ -z "$CAPTCHA_ID_VAL" ]]; then
142+
REQUEST_VALUE=$(json_str "$POLL_RESP" "request")
143+
# Unescape the JSON string and extract values
144+
UNESCAPED=$(echo "$REQUEST_VALUE" | sed 's/\\"/"/g; s/\\\\/\\/g')
145+
CAPTCHA_ID_VAL=$(echo "$UNESCAPED" | grep -oP '"captcha_id"\s*:\s*"\\K[^"]*' || echo "")
146+
LOT_NUMBER=$(echo "$UNESCAPED" | grep -oP '"lot_number"\s*:\s*"\\K[^"]*' || echo "")
147+
PASS_TOKEN=$(echo "$UNESCAPED" | grep -oP '"pass_token"\s*:\s*"\\K[^"]*' || echo "")
148+
GEN_TIME=$(echo "$UNESCAPED" | grep -oP '"gen_time"\s*:\s*"\\K[^"]*' || echo "")
149+
CAPTCHA_OUTPUT=$(echo "$UNESCAPED" | grep -oP '"captcha_output"\s*:\s*"\\K[^"]*' || echo "")
150+
fi
151+
152+
echo "[+] Solved!"
153+
echo "[+] captcha_id: $CAPTCHA_ID_VAL"
154+
echo "[+] lot_number: $LOT_NUMBER"
155+
echo "[+] pass_token: $PASS_TOKEN"
156+
echo "[+] gen_time: $GEN_TIME"
157+
echo "[+] captcha_output: $CAPTCHA_OUTPUT"
158+
echo
159+
echo "Next step: submit these five values to the site's"
160+
echo "GeeTest v4 verification endpoint."
161+
exit 0
162+
fi
163+
164+
REQUEST=$(json_str "$POLL_RESP" "request")
165+
166+
if [[ "$REQUEST" == "CAPCHA_NOT_READY" ]]; then
167+
echo "[*] Not ready yet, waiting ${POLL_INTERVAL}s..."
168+
sleep "$POLL_INTERVAL"
169+
ELAPSED=$((ELAPSED + POLL_INTERVAL))
170+
BACKOFF="$POLL_INTERVAL"
171+
continue
172+
fi
173+
174+
case "$REQUEST" in
175+
ERROR_SERVER_ERROR|ERROR_INTERNAL_SERVER_ERROR)
176+
echo "[!] Transient error: $REQUEST, retrying in ${BACKOFF}s..."
177+
sleep "$BACKOFF"
178+
ELAPSED=$((ELAPSED + BACKOFF))
179+
BACKOFF=$((BACKOFF * 2))
180+
[[ "$BACKOFF" -gt 30 ]] && BACKOFF=30
181+
continue
182+
;;
183+
ERROR_CAPTCHA_UNSOLVABLE)
184+
echo "[!] Solve error: $REQUEST"
185+
echo " The CAPTCHA could not be solved. Verify parameters and retry."
186+
exit 1
187+
;;
188+
esac
189+
190+
echo "[!] Unexpected error: $REQUEST"
191+
exit 1
192+
done
193+
194+
echo "[!] Timeout: no solution received within ${MAX_TIMEOUT} seconds."
195+
exit 1

0 commit comments

Comments
 (0)