anti_captcha 2.3.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +249 -144
- data/anti_captcha.gemspec +1 -1
- data/lib/anti_captcha/client.rb +125 -26
- data/lib/anti_captcha/models/geetest_solution.rb +30 -0
- data/lib/anti_captcha/models/h_captcha_solution.rb +5 -2
- data/lib/anti_captcha/models/{no_captcha_solution.rb → recaptcha_v2_solution.rb} +1 -1
- data/lib/anti_captcha/models/task_result.rb +1 -1
- data/lib/anti_captcha/models/turnstile_solution.rb +13 -0
- data/lib/anti_captcha/version.rb +1 -1
- data/lib/anti_captcha.rb +3 -1
- metadata +10 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7911a78f0b2ccdcb075555ea6ea96aa2abc6914311b792a4b2579ec1a3bc8901
|
4
|
+
data.tar.gz: f2e2df9d4ba1042fed67fed6d670dd6c22fc097f0856fa61e1da17a74483043c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1915d353fe91b85276cb5ace41c09b3762b8313c2903ab064f2f9fdb6572b151bfd2357f6a80f6883e4922773aeb096d3cca57c2939b309f093ef4f844cf181
|
7
|
+
data.tar.gz: cf6cdc10ac27031ccd362d8fb15da2af3d4e77cc849a4ab905854c831977b20c89a38fd47cad502f778d6b359493a45d4add2d0f5512f1984b0dcda23822e3a7
|
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
Developed by [Infosimples](https://infosimples.com).
|
2
|
-
|
3
1
|
# AntiCaptcha
|
4
2
|
|
5
|
-
AntiCaptcha is a Ruby API for Anti-Captcha - [Anti-Captcha.com](http://getcaptchasolution.com/ipuz16klxh)
|
3
|
+
AntiCaptcha is a Ruby API for Anti-Captcha - [Anti-Captcha.com](http://getcaptchasolution.com/ipuz16klxh)
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -14,215 +12,322 @@ gem 'anti_captcha'
|
|
14
12
|
|
15
13
|
And then execute:
|
16
14
|
|
17
|
-
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
````
|
18
18
|
|
19
19
|
Or install it yourself as:
|
20
20
|
|
21
|
-
|
21
|
+
```bash
|
22
|
+
$ gem install anti_captcha
|
23
|
+
````
|
22
24
|
|
23
25
|
## Usage
|
24
26
|
|
25
|
-
1.
|
26
|
-
|
27
|
-
```ruby
|
28
|
-
# Create a client
|
29
|
-
client = AntiCaptcha.new('my_key')
|
30
|
-
```
|
31
|
-
|
32
|
-
2. **Solve Image CAPTCHA**
|
33
|
-
|
34
|
-
There are two methods available:
|
27
|
+
### 1. Create a client
|
35
28
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
If the solution is not available, an empty solution object will be returned.
|
40
|
-
|
41
|
-
```ruby
|
42
|
-
solution = client.decode_image!(path: 'path/to/my/captcha/file')
|
43
|
-
solution.text # CAPTCHA solution.
|
44
|
-
solution.url # Image URL.
|
45
|
-
solution.task_result.task_id # The ID of the task.
|
46
|
-
```
|
47
|
-
|
48
|
-
You can also specify *file*, *body* and *body64* when decoding an image.
|
29
|
+
```ruby
|
30
|
+
client = AntiCaptcha.new('my_key')
|
31
|
+
```
|
49
32
|
|
50
|
-
|
51
|
-
client.decode_image!(file: File.open('path/to/my/captcha/file', 'rb'))
|
33
|
+
### 2. Solve a CAPTCHA
|
52
34
|
|
53
|
-
|
35
|
+
There are two types of methods available: `decode_*` and `decode_*!`:
|
54
36
|
|
55
|
-
|
56
|
-
|
37
|
+
- `decode_*` does not raise exceptions.
|
38
|
+
- `decode_*!` may raise a `AntiCaptcha::Error` if something goes wrong.
|
57
39
|
|
58
|
-
|
40
|
+
If the solution is not available, an empty solution object will be returned.
|
59
41
|
|
60
|
-
|
42
|
+
```ruby
|
43
|
+
solution = client.decode_image!(path: 'path/to/my/captcha/file')
|
44
|
+
solution.text # CAPTCHA solution
|
45
|
+
solution.url # Image URL
|
46
|
+
solution.task_result.task_id # The task ID
|
47
|
+
```
|
61
48
|
|
62
|
-
|
49
|
+
#### Image CAPTCHA
|
63
50
|
|
64
|
-
|
65
|
-
client.report_incorrect_image_catpcha!(task_id)
|
66
|
-
```
|
51
|
+
You can specify `file`, `body` or `body64` when decoding an image.
|
67
52
|
|
68
|
-
|
53
|
+
```ruby
|
54
|
+
client.decode_image!(file: File.open('path/to/my/captcha/file', 'rb'))
|
55
|
+
client.decode_image!(body: File.open('path/to/my/captcha/file', 'rb').read)
|
56
|
+
client.decode_image!(body64: Base64.encode64(File.open('path/to/my/captcha/file', 'rb').read))
|
57
|
+
```
|
69
58
|
|
70
|
-
|
71
|
-
client.get_balance!
|
72
|
-
```
|
59
|
+
#### reCAPTCHA v2
|
73
60
|
|
74
|
-
|
61
|
+
```ruby
|
62
|
+
solution = client.decode_recaptcha_v2!(
|
63
|
+
website_key: 'xyz',
|
64
|
+
website_url: 'http://example.com/example=1',
|
65
|
+
# proxy_type: 'http', # OPTIONAL
|
66
|
+
# proxy_address: '127.0.0.1', # OPTIONAL
|
67
|
+
# proxy_port: '8080', # OPTIONAL
|
68
|
+
# proxy_login: 'proxyLoginHere', # OPTIONAL
|
69
|
+
# proxy_password: 'proxyPasswordHere', # OPTIONAL
|
70
|
+
# user_agent: 'MODERN_USER_AGENT_HERE', # OPTIONAL
|
71
|
+
)
|
72
|
+
|
73
|
+
solution.g_recaptcha_response
|
74
|
+
"03AOPBWq_RPO2vLzyk0h8gH0cA2X4v3tpYCPZR6Y4yxKy1s3Eo7CHZRQntxrd..."
|
75
|
+
```
|
75
76
|
|
76
|
-
|
77
|
-
- `1` Standart ImageToText, English language.
|
78
|
-
- `2` Standart ImageToText, Russian language.
|
79
|
-
- `5` Recaptcha NoCaptcha tasks.
|
80
|
-
- `6` Recaptcha Proxyless task.
|
81
|
-
- `7` Funcaptcha task.
|
82
|
-
- `10` Funcaptcha Proxyless task.
|
83
|
-
- `18` Recaptcha V3 s0.3
|
84
|
-
- `19` Recaptcha V3 s0.7
|
85
|
-
- `20` Recaptcha V3 s0.9
|
86
|
-
- `21` hCaptcha Proxy-On
|
87
|
-
- `22` hCaptcha Proxyless
|
77
|
+
*Parameters:*
|
88
78
|
|
89
|
-
|
90
|
-
|
91
|
-
|
79
|
+
- `website_key`: the Google website key for the reCAPTCHA.
|
80
|
+
- `website_url`: the URL of the page with the reCAPTCHA challenge.
|
81
|
+
- `proxy_type`: optional parameter. Proxy connection protocol.
|
82
|
+
- `proxy_address`: optional parameter. The proxy address.
|
83
|
+
- `proxy_port`: optional parameter. The proxy port.
|
84
|
+
- `proxy_login`: optional parameter. The proxy login.
|
85
|
+
- `proxy_password`: optional parameter. The proxy password.
|
86
|
+
- `user_agent`: optional parameter. The user agent.
|
92
87
|
|
93
|
-
|
88
|
+
#### reCAPTCHA v3
|
94
89
|
|
95
|
-
|
96
|
-
|
90
|
+
```ruby
|
91
|
+
solution = client.decode_recaptcha_v3!(
|
92
|
+
website_key: 'xyz',
|
93
|
+
website_url: 'http://example.com/example=1',
|
94
|
+
page_action: 'myverify',
|
95
|
+
min_score: 0.3, # OPTIONAL
|
96
|
+
# is_enterprise: false, # OPTIONAL
|
97
|
+
)
|
98
|
+
|
99
|
+
solution.g_recaptcha_response
|
100
|
+
"03AOPBWq_RPO2vLzyk0h8gH0cA2X4v3tpYCPZR6Y4yxKy1s3Eo7CHZRQntxrd..."
|
101
|
+
```
|
97
102
|
|
98
|
-
|
103
|
+
*Parameters:*
|
99
104
|
|
100
|
-
|
101
|
-
|
105
|
+
- `website_key`: the Google website key for the reCAPTCHA.
|
106
|
+
- `website_url`: the URL of the page with the reCAPTCHA challenge.
|
107
|
+
- `action`: the action name used by the CAPTCHA.
|
108
|
+
- `min_score`: optional parameter. The minimal score needed for the CAPTCHA resolution. Defaults to `0.3`.
|
109
|
+
- `is_enterprise`: optional parameter. Set to `true` if you are solving a reCAPTCHA v3 Enterprise. Defaults to `false`.
|
102
110
|
|
103
|
-
|
111
|
+
> About the `action` parameter: in order to find out what this is, you need to inspect the JavaScript
|
112
|
+
> code of the website looking for a call to the `grecaptcha.execute` function.
|
113
|
+
>
|
114
|
+
> ```javascript
|
115
|
+
> // Example
|
116
|
+
> grecaptcha.execute('6Lc2fhwTAAAAAGatXTzFYfvlQMI2T7B6ji8UVV_f', { action: "examples/v3scores" })
|
117
|
+
> ````
|
104
118
|
|
105
|
-
|
106
|
-
|
119
|
+
> About the `min_score` parameter: it's strongly recommended to use a minimum score of `0.3` as higher
|
120
|
+
> scores are rare.
|
107
121
|
|
108
|
-
|
109
|
-
options = {
|
110
|
-
website_key: 'xyz',
|
111
|
-
website_url: 'http://example.com/example=1'
|
112
|
-
}
|
122
|
+
#### hCaptcha
|
113
123
|
|
114
|
-
|
115
|
-
|
116
|
-
|
124
|
+
```ruby
|
125
|
+
solution = client.decode_h_captcha!(
|
126
|
+
website_key: 'xyz',
|
127
|
+
website_url: 'http://example.com/example=1',
|
128
|
+
# proxy_type: 'http', # OPTIONAL
|
129
|
+
# proxy_address: '127.0.0.1', # OPTIONAL
|
130
|
+
# proxy_port: '8080', # OPTIONAL
|
131
|
+
# proxy_login: 'proxyLoginHere', # OPTIONAL
|
132
|
+
# proxy_password: 'proxyPasswordHere', # OPTIONAL
|
133
|
+
# user_agent: 'MODERN_USER_AGENT_HERE', # OPTIONAL
|
134
|
+
)
|
135
|
+
|
136
|
+
solution.token
|
137
|
+
"P0_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXNza2V5IjoiNnpWV..."
|
138
|
+
|
139
|
+
# Or
|
140
|
+
|
141
|
+
solution.g_recaptcha_response # Deprecated
|
142
|
+
"P0_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXNza2V5IjoiNnpWV..."
|
143
|
+
```
|
117
144
|
|
118
|
-
|
119
|
-
the form, like the following:
|
145
|
+
*Parameters:*
|
120
146
|
|
121
|
-
|
122
|
-
|
123
|
-
|
147
|
+
- `website_key`: the site key for the hCatpcha.
|
148
|
+
- `website_url`: the URL of the page with the hCaptcha challenge.
|
149
|
+
- `proxy_type`: optional parameter. Proxy connection protocol.
|
150
|
+
- `proxy_address`: optional parameter. The proxy address.
|
151
|
+
- `proxy_port`: optional parameter. The proxy port.
|
152
|
+
- `proxy_login`: optional parameter. The proxy login.
|
153
|
+
- `proxy_password`: optional parameter. The proxy password.
|
154
|
+
- `user_agent`: optional parameter. The user agent.
|
124
155
|
|
125
|
-
|
156
|
+
#### FunCaptcha
|
126
157
|
|
127
|
-
|
158
|
+
```ruby
|
159
|
+
solution = client.decode_fun_captcha!(
|
160
|
+
website_public_key: 'xyz',
|
161
|
+
website_url: 'http://example.com/example=1',
|
162
|
+
# proxy_type: 'http', # OPTIONAL
|
163
|
+
# proxy_address: '127.0.0.1', # OPTIONAL
|
164
|
+
# proxy_port: '8080', # OPTIONAL
|
165
|
+
# proxy_login: 'proxyLoginHere', # OPTIONAL
|
166
|
+
# proxy_password: 'proxyPasswordHere', # OPTIONAL
|
167
|
+
# user_agent: 'MODERN_USER_AGENT_HERE', # OPTIONAL
|
168
|
+
)
|
169
|
+
|
170
|
+
solution.token
|
171
|
+
"380633616d817f2b8.2351188603|r=ap-southeast-2|met..."
|
172
|
+
```
|
128
173
|
|
129
|
-
|
174
|
+
*Parameters:*
|
130
175
|
|
131
|
-
|
132
|
-
|
176
|
+
- `website_key`: the site key for the hCatpcha.
|
177
|
+
- `website_url`: the URL of the page with the hCaptcha challenge.
|
178
|
+
- `proxy_type`: optional parameter. Proxy connection protocol.
|
179
|
+
- `proxy_address`: optional parameter. The proxy address.
|
180
|
+
- `proxy_port`: optional parameter. The proxy port.
|
181
|
+
- `proxy_login`: optional parameter. The proxy login.
|
182
|
+
- `proxy_password`: optional parameter. The proxy password.
|
183
|
+
- `user_agent`: optional parameter. The user agent.
|
133
184
|
|
134
|
-
|
135
|
-
options = {
|
136
|
-
website_public_key: 'xyz',
|
137
|
-
website_url: 'http://example.com/example=1',
|
138
|
-
language_pool: '...'
|
139
|
-
}
|
185
|
+
#### Geetest
|
140
186
|
|
141
|
-
|
142
|
-
|
143
|
-
|
187
|
+
```ruby
|
188
|
+
solution = client.decode_geetest!(
|
189
|
+
website_url: 'http://mywebsite.com/geetest/test.php',
|
190
|
+
gt: '874703612e5cac182812a00e273aad0d',
|
191
|
+
challenge: 'a559b82bca2c500101a1c8a4f4204742',
|
192
|
+
# proxy_type: 'http', # OPTIONAL
|
193
|
+
# proxy_address: '127.0.0.1', # OPTIONAL
|
194
|
+
# proxy_port: '8080', # OPTIONAL
|
195
|
+
# proxy_login: 'proxyLoginHere', # OPTIONAL
|
196
|
+
# proxy_password: 'proxyPasswordHere', # OPTIONAL
|
197
|
+
# user_agent: 'MODERN_USER_AGENT_HERE', # OPTIONAL
|
198
|
+
)
|
144
199
|
|
145
|
-
|
200
|
+
solution.v3['challenge']
|
201
|
+
"3c1c5153aa48011e92883aed820069f3hj"
|
146
202
|
|
147
|
-
|
203
|
+
solution.v3['validate']
|
204
|
+
"47ad5a0a6eb98a95b2bcd9e9eecc8272"
|
148
205
|
|
149
|
-
|
206
|
+
solution.v3['seccode']
|
207
|
+
"83fa4f2d23005fc91c3a015a1613f803|jordan"
|
150
208
|
|
151
|
-
|
152
|
-
- `decode_recaptcha_v3!`: solves reCAPTCHA v3. It may raise an `AntiCaptcha::Error` if something goes wrong.
|
209
|
+
# Or
|
153
210
|
|
154
|
-
|
211
|
+
solution.v4['captcha_id']
|
212
|
+
"fcd636b4514bf7ac4143922550b3008b"
|
155
213
|
|
156
|
-
|
157
|
-
|
158
|
-
desire.
|
214
|
+
solution.v4['lot_number']
|
215
|
+
"354ab6dd4e594fdc903074c4d8d37b24"
|
159
216
|
|
160
|
-
|
217
|
+
solution.v4['pass_token']
|
218
|
+
"b645946a654e60218c7922b74b3b5ee8e8717e8fd3cd51..."
|
161
219
|
|
162
|
-
|
163
|
-
|
164
|
-
website_key: 'xyz',
|
165
|
-
website_url: 'http://example.com/example=1',
|
166
|
-
min_score: 0.3,
|
167
|
-
page_action: 'myverify'
|
168
|
-
}
|
220
|
+
solution.v4['gen_time']
|
221
|
+
"1649921519"
|
169
222
|
|
170
|
-
|
171
|
-
|
172
|
-
|
223
|
+
solution.v4['captcha_output']
|
224
|
+
"cFPIALDXSop8Ri2mPABbRWzNBs86N8D4vNUTuVa7wN7E..."
|
225
|
+
```
|
226
|
+
*Parameters:*
|
227
|
+
|
228
|
+
- `website_url`: URL of a target web page. It can be located anywhere on the web site, even in a member's area.
|
229
|
+
- `gt`: the domain's public key.
|
230
|
+
- `challenge`: changing token key. Make sure you grab a fresh one for each captcha.
|
231
|
+
- `geetest_api_server_subdomain`: optional parameter. API subdomain. May be required for some implementations.
|
232
|
+
- `geetest_get_lib`: optional parameter. Required for some implementations. Send the JSON encoded into a string. The value can be traced in the browser's developer tools. Put a breakpoint before calling the "initGeetest" function.
|
233
|
+
- `version`: optional parameter. Version number. Default version is 3. Supported versions: 3 and 4.
|
234
|
+
- `init_parameters`: optional parameter. Additional initialization parameters for version 4.
|
235
|
+
- `proxy_type`: optional parameter. Proxy connection protocol.
|
236
|
+
- `proxy_address`: optional parameter. The proxy address.
|
237
|
+
- `proxy_port`: optional parameter. The proxy port.
|
238
|
+
- `proxy_login`: optional parameter. The proxy login.
|
239
|
+
- `proxy_password`: optional parameter. The proxy password.
|
240
|
+
- `user_agent`: optional parameter. The user agent.
|
241
|
+
|
242
|
+
#### Cloudflare Turnstile
|
173
243
|
|
174
|
-
|
175
|
-
|
244
|
+
```ruby
|
245
|
+
solution = client.decode_turnstile!(
|
246
|
+
website_key: 'xyz',
|
247
|
+
website_url: 'http://example.com/example=1',
|
248
|
+
# proxy_type: 'http', # OPTIONAL
|
249
|
+
# proxy_address: '127.0.0.1', # OPTIONAL
|
250
|
+
# proxy_port: '8080', # OPTIONAL
|
251
|
+
# proxy_login: 'proxyLoginHere', # OPTIONAL
|
252
|
+
# proxy_password: 'proxyPasswordHere', # OPTIONAL
|
253
|
+
)
|
254
|
+
|
255
|
+
solution.token
|
256
|
+
"0.vtJqmZnvobaUzK2i2PyKaSqHELYtBZfRoPwMvLMdA81WL_9G0vCO3y2VQVIeVplG0mxYF7uX......."
|
257
|
+
```
|
176
258
|
|
177
|
-
|
178
|
-
"1JJHJ_VuuHAqJKxcaasbTsqw-L1Sm4gD57PTeaEr9-MaETG1vfu2H5zlcwkjsRoZoHxx6V9yUDw8Ig-hYD8kakmSnnjNQd50w_Y_tI3aDLp-s_7ZmhH6pcaoWWsid5hdtMXyvrP9DscDuCLBf7etLle8caPWSaYCpAq9DOTtj5NpSg6-OeCJdGdkjsakFUMeGeqmje87wSajcjmdjl_w4XZBY2zy8fUH6XoAGZ6AeCTulIljBQDObQynKDd-rutPvKNxZasDk-LbhTfw508g1lu9io6jnvm3kbAdnkfZ0x0PkGiUMHU7hnuoW6bXo2Yn_Zt5tDWL7N7wFtY6B0k7cTy73f8er508zReOuoyz2NqL8smDCmcJu05ajkPGt20qzpURMwHaw"
|
179
|
-
```
|
259
|
+
*Parameters:*
|
180
260
|
|
181
|
-
|
261
|
+
- `website_key`: the site key for the Turnstile.
|
262
|
+
- `website_url`: the URL of the page with the Turnstile challenge.
|
263
|
+
- `proxy_type`: optional parameter. Proxy connection protocol.
|
264
|
+
- `proxy_address`: optional parameter. The proxy address.
|
265
|
+
- `proxy_port`: optional parameter. The proxy port.
|
266
|
+
- `proxy_login`: optional parameter. The proxy login.
|
267
|
+
- `proxy_password`: optional parameter. The proxy password.
|
182
268
|
|
183
|
-
|
269
|
+
### 3. Report an incorrectly solved image CAPTCHA for a refund
|
184
270
|
|
185
|
-
|
271
|
+
It is only possible to report incorrectly solved image CAPTCHAs.
|
186
272
|
|
187
|
-
|
188
|
-
|
273
|
+
```ruby
|
274
|
+
client.report_incorrect_image_catpcha!(task_id)
|
275
|
+
```
|
189
276
|
|
190
|
-
|
277
|
+
### 4. Get your account balance
|
191
278
|
|
192
|
-
|
193
|
-
|
279
|
+
```ruby
|
280
|
+
client.get_balance!
|
281
|
+
```
|
194
282
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
283
|
+
### 5. Get current stats of a queue.
|
284
|
+
|
285
|
+
Queue IDs:
|
286
|
+
|
287
|
+
- `1` Standart ImageToText, English language
|
288
|
+
- `2` Standart ImageToText, Russian language
|
289
|
+
- `5` Recaptcha NoCaptcha tasks
|
290
|
+
- `6` Recaptcha Proxyless task
|
291
|
+
- `7` Funcaptcha task
|
292
|
+
- `10` Funcaptcha Proxyless task
|
293
|
+
- `12` GeeTest with proxy
|
294
|
+
- `13` GeeTest without proxy
|
295
|
+
- `18` Recaptcha V3 s0.3
|
296
|
+
- `19` Recaptcha V3 s0.7
|
297
|
+
- `20` Recaptcha V3 s0.9
|
298
|
+
- `21` hCaptcha with proxy
|
299
|
+
- `22` hCaptcha without proxy
|
300
|
+
- `23` Recaptcha Enterprise V2 with proxy
|
301
|
+
- `24` Recaptcha Enterprise V2 without proxy
|
302
|
+
- `25` AntiGateTask
|
303
|
+
- `26` Turnstile with proxy
|
304
|
+
- `27` Turnstile without proxy
|
200
305
|
|
201
|
-
|
202
|
-
|
203
|
-
|
306
|
+
```ruby
|
307
|
+
client.get_queue_stats!(queue_id)
|
308
|
+
```
|
204
309
|
|
205
310
|
## Notes
|
206
311
|
|
207
|
-
|
312
|
+
### Ruby dependencies
|
208
313
|
|
209
314
|
AntiCaptcha doesn't require specific dependencies. That saves you memory and
|
210
315
|
avoid conflicts with other gems.
|
211
316
|
|
212
|
-
|
317
|
+
### Input image format
|
213
318
|
|
214
|
-
Any format you use in the
|
215
|
-
be converted to a body64
|
216
|
-
already have this format
|
217
|
-
|
319
|
+
Any format you use in the `decode_image!` method (`file`, `path`, `body` or `body64`)
|
320
|
+
will always be converted to a `body64`, which is a base64-encoded binary string.
|
321
|
+
So, if you already have this format on your end, there is no need for convertions
|
322
|
+
before calling the API.
|
218
323
|
|
219
324
|
> Our recomendation is to never convert your image format, unless needed. Let
|
220
325
|
> the gem convert internally. It may save you resources (CPU, memory and IO).
|
221
326
|
|
222
|
-
|
327
|
+
### Versioning
|
223
328
|
|
224
329
|
AntiCaptcha gem uses [Semantic Versioning](http://semver.org/).
|
225
330
|
|
226
331
|
# License
|
227
332
|
|
228
|
-
MIT License. Copyright (C) 2011-
|
333
|
+
MIT License. Copyright (C) 2011-2022 Infosimples. https://infosimples.com/
|
data/anti_captcha.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
22
|
spec.require_paths = ["lib"]
|
23
23
|
|
24
|
-
spec.add_development_dependency "bundler", "
|
24
|
+
spec.add_development_dependency "bundler", ">= 2.2.33"
|
25
25
|
spec.add_development_dependency "rake", "~> 12.3.3"
|
26
26
|
spec.add_development_dependency "rspec", "~> 3.0"
|
27
27
|
end
|
data/lib/anti_captcha/client.rb
CHANGED
@@ -4,8 +4,7 @@ module AntiCaptcha
|
|
4
4
|
#
|
5
5
|
class Client
|
6
6
|
BASE_URL = 'https://api.anti-captcha.com/:action'
|
7
|
-
PROXYABLE_TASKS = %w(
|
8
|
-
SUPPORTED_TASKS = %w(ImageToTextTask NoCaptchaTask FunCaptchaTask HCaptchaTask)
|
7
|
+
PROXYABLE_TASKS = %w(RecaptchaV2Task FunCaptchaTask HCaptchaTask GeeTestTask TurnstileTask)
|
9
8
|
|
10
9
|
attr_accessor :client_key, :timeout, :polling
|
11
10
|
|
@@ -14,7 +13,7 @@ module AntiCaptcha
|
|
14
13
|
#
|
15
14
|
# @param [String] client_key The key of the Anti Captcha account.
|
16
15
|
# @param [Hash] options Options hash.
|
17
|
-
# @option options [Integer] :timeout (
|
16
|
+
# @option options [Integer] :timeout (120) Seconds before giving up of a
|
18
17
|
# captcha being solved.
|
19
18
|
# @option options [Integer] :polling (5) Seconds before checking answer
|
20
19
|
# again.
|
@@ -23,7 +22,7 @@ module AntiCaptcha
|
|
23
22
|
#
|
24
23
|
def initialize(client_key, options = {})
|
25
24
|
self.client_key = client_key
|
26
|
-
self.timeout = options[:timeout] ||
|
25
|
+
self.timeout = options[:timeout] || 120
|
27
26
|
self.polling = options[:polling] || 5
|
28
27
|
end
|
29
28
|
|
@@ -75,18 +74,19 @@ module AntiCaptcha
|
|
75
74
|
end
|
76
75
|
|
77
76
|
#
|
78
|
-
# Decodes a NoCaptcha
|
77
|
+
# Decodes a reCAPTCHA v2 (NoCaptcha).
|
79
78
|
#
|
80
|
-
# @see `AntiCaptcha::Client#
|
79
|
+
# @see `AntiCaptcha::Client#decode_recaptcha_v2!`
|
81
80
|
#
|
82
|
-
def
|
83
|
-
|
81
|
+
def decode_recaptcha_v2(options, proxy = nil)
|
82
|
+
decode_recaptcha_v2!(options, proxy)
|
84
83
|
rescue
|
85
|
-
AntiCaptcha::
|
84
|
+
AntiCaptcha::RecaptchaV2Solution.new
|
86
85
|
end
|
86
|
+
alias :decode_nocaptcha :decode_recaptcha_v2
|
87
87
|
|
88
88
|
#
|
89
|
-
# Decodes a NoCaptcha
|
89
|
+
# Decodes a reCAPTCHA v2 (NoCaptcha).
|
90
90
|
#
|
91
91
|
# @param [Hash] options Options hash.
|
92
92
|
# @option options [String] :website_url
|
@@ -103,16 +103,17 @@ module AntiCaptcha
|
|
103
103
|
# @option proxy [String] :proxy_password
|
104
104
|
# @option proxy [String] :user_agent
|
105
105
|
#
|
106
|
-
# @return [AntiCaptcha::
|
106
|
+
# @return [AntiCaptcha::RecaptchaV2Solution] The solution of the reCAPTCHA v2.
|
107
107
|
#
|
108
|
-
def
|
109
|
-
task = create_task!('
|
108
|
+
def decode_recaptcha_v2!(options, proxy = nil)
|
109
|
+
task = create_task!('RecaptchaV2Task', options, proxy)
|
110
110
|
task_result = get_task_result!(task['taskId'])
|
111
|
-
AntiCaptcha::
|
111
|
+
AntiCaptcha::RecaptchaV2Solution.new(task_result)
|
112
112
|
end
|
113
|
+
alias :decode_nocaptcha! :decode_recaptcha_v2!
|
113
114
|
|
114
115
|
#
|
115
|
-
# Decodes a reCAPTCHA
|
116
|
+
# Decodes a reCAPTCHA v3.
|
116
117
|
#
|
117
118
|
# @see `AntiCaptcha::Client#decode_recaptcha_v3!`
|
118
119
|
#
|
@@ -123,17 +124,18 @@ module AntiCaptcha
|
|
123
124
|
end
|
124
125
|
|
125
126
|
#
|
126
|
-
# Decodes a reCAPTCHA
|
127
|
+
# Decodes a reCAPTCHA v3. Proxy is not supported.
|
127
128
|
#
|
128
129
|
# @param [Hash] options Options hash.
|
129
130
|
# @option options [String] :website_url
|
130
131
|
# @option options [String] :website_key
|
131
132
|
# @option options [String] :min_score (one of 0.3, 0,5 or 0.7)
|
132
133
|
# @option options [String] :page_action
|
134
|
+
# @option options [String] :is_enterprise
|
133
135
|
# @option options [String] :language_pool
|
134
136
|
#
|
135
137
|
# @return [AntiCaptcha::RecaptchaV3Solution] The solution of
|
136
|
-
# the reCAPTCHA
|
138
|
+
# the reCAPTCHA v3.
|
137
139
|
#
|
138
140
|
def decode_recaptcha_v3!(options)
|
139
141
|
task = create_task!('RecaptchaV3TaskProxyless', options)
|
@@ -203,6 +205,81 @@ module AntiCaptcha
|
|
203
205
|
AntiCaptcha::HCaptchaSolution.new(task_result)
|
204
206
|
end
|
205
207
|
|
208
|
+
#
|
209
|
+
# Decodes a Geetest CAPTCHA.
|
210
|
+
#
|
211
|
+
# @see `AntiCaptcha::Client#decode_geetest!`
|
212
|
+
#
|
213
|
+
def decode_geetest(options, proxy = nil)
|
214
|
+
decode_geetest!(options, proxy)
|
215
|
+
rescue
|
216
|
+
AntiCaptcha::GeetestSolution.new
|
217
|
+
end
|
218
|
+
|
219
|
+
#
|
220
|
+
# Decodes a Geetest CAPTCHA.
|
221
|
+
#
|
222
|
+
# @param [Hash] options Options hash.
|
223
|
+
# @option options [String] :website_url
|
224
|
+
# @option options [String] :gt
|
225
|
+
# @option options [String] :challenge
|
226
|
+
# @option options [String] :geetest_api_server_subdomain
|
227
|
+
# @option options [String] :geetest_get_lib
|
228
|
+
# @option options [String] :version
|
229
|
+
# @option options [String] :init_parameters
|
230
|
+
#
|
231
|
+
# @param [Hash] proxy Not mandatory. A hash with configs of the proxy that
|
232
|
+
# has to be used. Defaults to `nil`.
|
233
|
+
# @option proxy [String] :proxy_type
|
234
|
+
# @option proxy [String] :proxy_address
|
235
|
+
# @option proxy [String] :proxy_port
|
236
|
+
# @option proxy [String] :proxy_login
|
237
|
+
# @option proxy [String] :proxy_login
|
238
|
+
# @option proxy [String] :proxy_password
|
239
|
+
# @option proxy [String] :user_agent
|
240
|
+
#
|
241
|
+
# @return [AntiCaptcha::GeetestSolution] The solution of the Geetest.
|
242
|
+
#
|
243
|
+
def decode_geetest!(options, proxy = nil)
|
244
|
+
task = create_task!('GeeTestTask', options, proxy)
|
245
|
+
task_result = get_task_result!(task['taskId'])
|
246
|
+
AntiCaptcha::GeetestSolution.new(task_result)
|
247
|
+
end
|
248
|
+
|
249
|
+
#
|
250
|
+
# Decodes a Turnstile CAPTCHA.
|
251
|
+
#
|
252
|
+
# @see `AntiCaptcha::Client#decode_turnstile!`
|
253
|
+
#
|
254
|
+
def decode_turnstile(options, proxy = nil)
|
255
|
+
decode_turnstile!(options, proxy)
|
256
|
+
rescue
|
257
|
+
AntiCaptcha::TurnstileSolution.new
|
258
|
+
end
|
259
|
+
|
260
|
+
#
|
261
|
+
# Decodes a Turnstile CAPTCHA.
|
262
|
+
#
|
263
|
+
# @param [Hash] options Options hash.
|
264
|
+
# @option options [String] :website_url
|
265
|
+
# @option options [String] :website_key
|
266
|
+
#
|
267
|
+
# @param [Hash] proxy Not mandatory. A hash with configs of the proxy that
|
268
|
+
# has to be used. Defaults to `nil`.
|
269
|
+
# @option proxy [String] :proxy_type
|
270
|
+
# @option proxy [String] :proxy_address
|
271
|
+
# @option proxy [String] :proxy_port
|
272
|
+
# @option proxy [String] :proxy_login
|
273
|
+
# @option proxy [String] :proxy_password
|
274
|
+
#
|
275
|
+
# @return [AntiCaptcha::TurnstileSolution] The solution of the Turnstile.
|
276
|
+
#
|
277
|
+
def decode_turnstile!(options, proxy = nil)
|
278
|
+
task = create_task!('TurnstileTask', options, proxy)
|
279
|
+
task_result = get_task_result!(task['taskId'])
|
280
|
+
AntiCaptcha::TurnstileSolution.new(task_result)
|
281
|
+
end
|
282
|
+
|
206
283
|
# Creates a task for solving the selected CAPTCHA type.
|
207
284
|
#
|
208
285
|
# @param [String] type The type of the CAPTCHA.
|
@@ -262,9 +339,9 @@ module AntiCaptcha
|
|
262
339
|
comment: options[:comment],
|
263
340
|
}
|
264
341
|
|
265
|
-
when '
|
342
|
+
when 'RecaptchaV2Task'
|
266
343
|
args[:task] = {
|
267
|
-
type: '
|
344
|
+
type: 'RecaptchaV2Task',
|
268
345
|
websiteURL: options[:website_url],
|
269
346
|
websiteKey: options[:website_key],
|
270
347
|
}
|
@@ -272,11 +349,13 @@ module AntiCaptcha
|
|
272
349
|
when 'RecaptchaV3TaskProxyless'
|
273
350
|
args[:task] = {
|
274
351
|
type: 'RecaptchaV3TaskProxyless',
|
275
|
-
websiteURL:
|
276
|
-
websiteKey:
|
277
|
-
minScore:
|
278
|
-
pageAction:
|
352
|
+
websiteURL: options[:website_url],
|
353
|
+
websiteKey: options[:website_key],
|
354
|
+
minScore: (options[:min_score] || 0.3).to_f,
|
355
|
+
pageAction: options[:page_action],
|
279
356
|
}
|
357
|
+
args[:isEnterprise] = options[:is_enterprise] if [true, false].include?(options[:is_enterprise])
|
358
|
+
|
280
359
|
|
281
360
|
when 'FunCaptchaTask'
|
282
361
|
args[:task] = {
|
@@ -287,14 +366,32 @@ module AntiCaptcha
|
|
287
366
|
|
288
367
|
when 'HCaptchaTask'
|
289
368
|
args[:task] = {
|
290
|
-
type:
|
369
|
+
type: 'HCaptchaTask',
|
370
|
+
websiteURL: options[:website_url],
|
371
|
+
websiteKey: options[:website_key],
|
372
|
+
}
|
373
|
+
|
374
|
+
when 'GeeTestTask'
|
375
|
+
args[:task] = {
|
376
|
+
type: 'GeeTestTask',
|
377
|
+
websiteURL: options[:website_url],
|
378
|
+
gt: options[:gt],
|
379
|
+
challenge: options[:challenge],
|
380
|
+
}
|
381
|
+
args[:geetestApiServerSubdomain] = options[:geetest_api_server_subdomain] if !options[:geetest_api_server_subdomain].nil?
|
382
|
+
args[:geetestGetLib] = options[:geetest_get_lib] if !options[:geetest_get_lib].nil?
|
383
|
+
args[:version] = options[:version] if !options[:version].nil?
|
384
|
+
args[:initParameters] = options[:init_parameters] if !options[:init_parameters].nil?
|
385
|
+
|
386
|
+
when 'TurnstileTask'
|
387
|
+
args[:task] = {
|
388
|
+
type: 'TurnstileTask',
|
291
389
|
websiteURL: options[:website_url],
|
292
390
|
websiteKey: options[:website_key],
|
293
391
|
}
|
294
392
|
|
295
393
|
else
|
296
|
-
message = "Invalid task type: '#{type}'.
|
297
|
-
"#{SUPPORTED_TASKS.join(', ')}"
|
394
|
+
message = "Invalid task type: '#{type}'."
|
298
395
|
raise AntiCaptcha::ArgumentError.new(message)
|
299
396
|
end
|
300
397
|
|
@@ -365,6 +462,8 @@ module AntiCaptcha
|
|
365
462
|
# 20 - Recaptcha V3 s0.9
|
366
463
|
# 21 - hCaptcha Proxy-On
|
367
464
|
# 22 - hCaptcha Proxyless
|
465
|
+
# 26 - Turnstile Proxy-On
|
466
|
+
# 27 - Turnstile Proxyless
|
368
467
|
#
|
369
468
|
# @return [Hash] Information about the queue.
|
370
469
|
#
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module AntiCaptcha
|
2
|
+
class GeetestSolution < AntiCaptcha::Solution
|
3
|
+
attr_accessor :v3, :v4
|
4
|
+
|
5
|
+
def initialize(task_result = nil)
|
6
|
+
super
|
7
|
+
|
8
|
+
if task_result
|
9
|
+
solution = task_result.api_result['solution']
|
10
|
+
|
11
|
+
if solution['pass_token']
|
12
|
+
@v4 = {
|
13
|
+
'captcha_id' => solution['captcha_id'],
|
14
|
+
'lot_number' => solution['lot_number'],
|
15
|
+
'pass_token' => solution['pass_token'],
|
16
|
+
'gen_time' => solution['gen_time'],
|
17
|
+
'captcha_output' => solution['captcha_output'],
|
18
|
+
}
|
19
|
+
|
20
|
+
else
|
21
|
+
@v3 = {
|
22
|
+
'challenge' => solution['challenge'],
|
23
|
+
'validate' => solution['validate'],
|
24
|
+
'seccode' => solution['seccode'],
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,12 +1,15 @@
|
|
1
1
|
module AntiCaptcha
|
2
2
|
class HCaptchaSolution < AntiCaptcha::Solution
|
3
|
-
attr_accessor :g_recaptcha_response
|
3
|
+
attr_accessor :g_recaptcha_response # Deprecated
|
4
|
+
attr_accessor :token
|
5
|
+
|
4
6
|
|
5
7
|
def initialize(task_result = nil)
|
6
8
|
super
|
7
9
|
|
8
10
|
if task_result
|
9
|
-
@
|
11
|
+
@token = task_result.api_result['solution']['gRecaptchaResponse']
|
12
|
+
@g_recaptcha_response = token
|
10
13
|
end
|
11
14
|
end
|
12
15
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module AntiCaptcha
|
2
2
|
class TaskResult < AntiCaptcha::Model
|
3
3
|
attr_accessor :task_id, :error_id, :error_code, :error_description, :status,
|
4
|
-
|
4
|
+
:cost, :ip, :create_time, :end_time, :solve_count, :api_result
|
5
5
|
|
6
6
|
def initialize(api_result, task_id)
|
7
7
|
@task_id = task_id
|
data/lib/anti_captcha/version.rb
CHANGED
data/lib/anti_captcha.rb
CHANGED
@@ -33,10 +33,12 @@ require 'anti_captcha/http'
|
|
33
33
|
require 'anti_captcha/errors'
|
34
34
|
require 'anti_captcha/models/solution'
|
35
35
|
require 'anti_captcha/models/image_to_text_solution'
|
36
|
-
require 'anti_captcha/models/
|
36
|
+
require 'anti_captcha/models/recaptcha_v2_solution'
|
37
37
|
require 'anti_captcha/models/recaptcha_v3_solution'
|
38
38
|
require 'anti_captcha/models/fun_captcha_solution'
|
39
39
|
require 'anti_captcha/models/h_captcha_solution'
|
40
|
+
require 'anti_captcha/models/geetest_solution'
|
41
|
+
require 'anti_captcha/models/turnstile_solution'
|
40
42
|
require 'anti_captcha/models/task_result'
|
41
43
|
require 'anti_captcha/client'
|
42
44
|
require 'anti_captcha/version'
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: anti_captcha
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Infosimples
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.2.33
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 2.2.33
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,12 +75,14 @@ files:
|
|
75
75
|
- lib/anti_captcha/errors.rb
|
76
76
|
- lib/anti_captcha/http.rb
|
77
77
|
- lib/anti_captcha/models/fun_captcha_solution.rb
|
78
|
+
- lib/anti_captcha/models/geetest_solution.rb
|
78
79
|
- lib/anti_captcha/models/h_captcha_solution.rb
|
79
80
|
- lib/anti_captcha/models/image_to_text_solution.rb
|
80
|
-
- lib/anti_captcha/models/
|
81
|
+
- lib/anti_captcha/models/recaptcha_v2_solution.rb
|
81
82
|
- lib/anti_captcha/models/recaptcha_v3_solution.rb
|
82
83
|
- lib/anti_captcha/models/solution.rb
|
83
84
|
- lib/anti_captcha/models/task_result.rb
|
85
|
+
- lib/anti_captcha/models/turnstile_solution.rb
|
84
86
|
- lib/anti_captcha/version.rb
|
85
87
|
homepage: https://github.com/infosimples/anti_captcha
|
86
88
|
licenses:
|
@@ -101,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
103
|
- !ruby/object:Gem::Version
|
102
104
|
version: '0'
|
103
105
|
requirements: []
|
104
|
-
rubygems_version: 3.
|
106
|
+
rubygems_version: 3.5.6
|
105
107
|
signing_key:
|
106
108
|
specification_version: 4
|
107
109
|
summary: Ruby API for Anti Captcha (CAPTCHA Solver as a Service)
|