anti_captcha 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +228 -149
- data/anti_captcha.gemspec +1 -1
- data/lib/anti_captcha/client.rb +82 -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/version.rb +1 -1
- data/lib/anti_captcha.rb +2 -1
- metadata +12 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c007c351a8655684c2f4680ead884429b8bea0ebd1fb33568119b15b477fcc76
|
|
4
|
+
data.tar.gz: 38267b78fb266cbb281a3d28db9cf32633398798a270bdc9e2bbd4f87cc2d84a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6bd0a5e3759806d4d88285d819a2d18738a47d560d2a4a25ab6497d1a7d12b3e07a34f0e7c2d1ac5755a1b7238a975fc45b49594019076f0fd53584dee67e085
|
|
7
|
+
data.tar.gz: 43a55d65f865c263b0fa732984a085b92ae5936530f8d6f6cc5a7e619e261629a3c4991907a85838b76968e73827270d3e580938c9adea23280a27a52e000ab4
|
data/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
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)
|
|
4
|
+
|
|
5
|
+
> We suggest you to also check the recommended CAPTCHA provider DeathByCaptcha.
|
|
6
|
+
> The gem for this provider is available at https://github.com/infosimples/deathbycaptcha.
|
|
6
7
|
|
|
7
8
|
## Installation
|
|
8
9
|
|
|
@@ -14,215 +15,293 @@ gem 'anti_captcha'
|
|
|
14
15
|
|
|
15
16
|
And then execute:
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
```bash
|
|
19
|
+
$ bundle
|
|
20
|
+
````
|
|
18
21
|
|
|
19
22
|
Or install it yourself as:
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
```bash
|
|
25
|
+
$ gem install anti_captcha
|
|
26
|
+
````
|
|
22
27
|
|
|
23
28
|
## Usage
|
|
24
29
|
|
|
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:
|
|
35
|
-
|
|
36
|
-
- `decode_image`: solves image CAPTCHAs. It doesn't raise exceptions.
|
|
37
|
-
- `decode_image!`: solves image CAPTCHAs. It may raise an `AntiCaptcha::Error` if something goes wrong.
|
|
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.
|
|
30
|
+
### 1. Create a client
|
|
49
31
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
client.decode_image!(body: File.open('path/to/my/captcha/file', 'rb').read)
|
|
54
|
-
|
|
55
|
-
client.decode_image!(body64: Base64.encode64(File.open('path/to/my/captcha/file', 'rb').read))
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
> Internally, the gem will always convert the image to body64 (binary base64 encoded).
|
|
59
|
-
|
|
60
|
-
3. **Report incorrectly solved image CAPTCHA for refund**
|
|
32
|
+
```ruby
|
|
33
|
+
client = AntiCaptcha.new('my_key')
|
|
34
|
+
```
|
|
61
35
|
|
|
62
|
-
|
|
36
|
+
### 2. Solve a CAPTCHA
|
|
63
37
|
|
|
64
|
-
|
|
65
|
-
client.report_incorrect_image_catpcha!(task_id)
|
|
66
|
-
```
|
|
38
|
+
There are two types of methods available: `decode_*` and `decode_*!`:
|
|
67
39
|
|
|
68
|
-
|
|
40
|
+
- `decode_*` does not raise exceptions.
|
|
41
|
+
- `decode_*!` may raise a `AntiCaptcha::Error` if something goes wrong.
|
|
69
42
|
|
|
70
|
-
|
|
71
|
-
client.get_balance!
|
|
72
|
-
```
|
|
43
|
+
If the solution is not available, an empty solution object will be returned.
|
|
73
44
|
|
|
74
|
-
|
|
45
|
+
```ruby
|
|
46
|
+
solution = client.decode_image!(path: 'path/to/my/captcha/file')
|
|
47
|
+
solution.text # CAPTCHA solution
|
|
48
|
+
solution.url # Image URL
|
|
49
|
+
solution.task_result.task_id # The task ID
|
|
50
|
+
```
|
|
75
51
|
|
|
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
|
|
52
|
+
#### Image CAPTCHA
|
|
88
53
|
|
|
89
|
-
|
|
90
|
-
client.get_queue_stats!(queue_id)
|
|
91
|
-
```
|
|
54
|
+
You can specify `file`, `body` or `body64` when decoding an image.
|
|
92
55
|
|
|
93
|
-
|
|
56
|
+
```ruby
|
|
57
|
+
client.decode_image!(file: File.open('path/to/my/captcha/file', 'rb'))
|
|
58
|
+
client.decode_image!(body: File.open('path/to/my/captcha/file', 'rb').read)
|
|
59
|
+
client.decode_image!(body64: Base64.encode64(File.open('path/to/my/captcha/file', 'rb').read))
|
|
60
|
+
```
|
|
94
61
|
|
|
95
|
-
|
|
96
|
-
[reCAPTCHA v2](https://support.google.com/recaptcha/?hl=en#6262736).
|
|
62
|
+
#### reCAPTCHA v2
|
|
97
63
|
|
|
98
|
-
|
|
64
|
+
```ruby
|
|
65
|
+
solution = client.decode_recaptcha_v2!(
|
|
66
|
+
website_key: 'xyz',
|
|
67
|
+
website_url: 'http://example.com/example=1',
|
|
68
|
+
# proxy_type: 'http', # OPTIONAL
|
|
69
|
+
# proxy_address: '127.0.0.1', # OPTIONAL
|
|
70
|
+
# proxy_port: '8080', # OPTIONAL
|
|
71
|
+
# proxy_login: 'proxyLoginHere', # OPTIONAL
|
|
72
|
+
# proxy_password: 'proxyPasswordHere', # OPTIONAL
|
|
73
|
+
# user_agent: 'MODERN_USER_AGENT_HERE', # OPTIONAL
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
solution.g_recaptcha_response
|
|
77
|
+
"03AOPBWq_RPO2vLzyk0h8gH0cA2X4v3tpYCPZR6Y4yxKy1s3Eo7CHZRQntxrd..."
|
|
78
|
+
```
|
|
99
79
|
|
|
100
|
-
|
|
101
|
-
- `decode_nocaptcha!`: solves NoCaptcha CAPTCHAs. It may raise an `AntiCaptcha::Error` if something goes wrong.
|
|
80
|
+
*Parameters:*
|
|
102
81
|
|
|
103
|
-
|
|
82
|
+
- `website_key`: the Google website key for the reCAPTCHA.
|
|
83
|
+
- `website_url`: the URL of the page with the reCAPTCHA challenge.
|
|
84
|
+
- `proxy_type`: optional parameter. Proxy connection protocol.
|
|
85
|
+
- `proxy_address`: optional parameter. The proxy address.
|
|
86
|
+
- `proxy_port`: optional parameter. The proxy port.
|
|
87
|
+
- `proxy_login`: optional parameter. The proxy login.
|
|
88
|
+
- `proxy_password`: optional parameter. The proxy password.
|
|
89
|
+
- `user_agent`: optional parameter. The user agent.
|
|
104
90
|
|
|
105
|
-
|
|
106
|
-
identify the website in which the CAPTCHA is found.
|
|
91
|
+
#### reCAPTCHA v3
|
|
107
92
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
93
|
+
```ruby
|
|
94
|
+
solution = client.decode_recaptcha_v3!(
|
|
95
|
+
website_key: 'xyz',
|
|
96
|
+
website_url: 'http://example.com/example=1',
|
|
97
|
+
min_score: 0.3,
|
|
98
|
+
page_action: 'myverify',
|
|
99
|
+
# is_enterprise: false, # OPTIONAL
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
solution.g_recaptcha_response
|
|
103
|
+
"03AOPBWq_RPO2vLzyk0h8gH0cA2X4v3tpYCPZR6Y4yxKy1s3Eo7CHZRQntxrd..."
|
|
104
|
+
```
|
|
113
105
|
|
|
114
|
-
|
|
115
|
-
solution.g_recaptcha_response # Solution of the captcha
|
|
116
|
-
```
|
|
106
|
+
*Parameters:*
|
|
117
107
|
|
|
118
|
-
|
|
119
|
-
|
|
108
|
+
- `website_key`: the Google website key for the reCAPTCHA.
|
|
109
|
+
- `website_url`: the URL of the page with the reCAPTCHA challenge.
|
|
110
|
+
- `action`: the action name used by the CAPTCHA.
|
|
111
|
+
- `min_score`: optional parameter. The minimal score needed for the CAPTCHA resolution. Defaults to `0.3`.
|
|
112
|
+
- `is_enterprise`: optional parameter. Set to `true` if you are solving a reCAPTCHA v3 Enterprise. Defaults to `false`.
|
|
120
113
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
114
|
+
> About the `action` parameter: in order to find out what this is, you need to inspect the JavaScript
|
|
115
|
+
> code of the website looking for a call to the `grecaptcha.execute` function.
|
|
116
|
+
>
|
|
117
|
+
> ```javascript
|
|
118
|
+
> // Example
|
|
119
|
+
> grecaptcha.execute('6Lc2fhwTAAAAAGatXTzFYfvlQMI2T7B6ji8UVV_f', { action: "examples/v3scores" })
|
|
120
|
+
> ````
|
|
124
121
|
|
|
125
|
-
|
|
122
|
+
> About the `min_score` parameter: it's strongly recommended to use a minimum score of `0.3` as higher
|
|
123
|
+
> scores are rare.
|
|
126
124
|
|
|
127
|
-
|
|
125
|
+
#### hCaptcha
|
|
128
126
|
|
|
129
|
-
|
|
127
|
+
```ruby
|
|
128
|
+
solution = client.decode_h_captcha!(
|
|
129
|
+
website_key: 'xyz',
|
|
130
|
+
website_url: 'http://example.com/example=1',
|
|
131
|
+
# proxy_type: 'http', # OPTIONAL
|
|
132
|
+
# proxy_address: '127.0.0.1', # OPTIONAL
|
|
133
|
+
# proxy_port: '8080', # OPTIONAL
|
|
134
|
+
# proxy_login: 'proxyLoginHere', # OPTIONAL
|
|
135
|
+
# proxy_password: 'proxyPasswordHere', # OPTIONAL
|
|
136
|
+
# user_agent: 'MODERN_USER_AGENT_HERE', # OPTIONAL
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
solution.token
|
|
140
|
+
"P0_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXNza2V5IjoiNnpWV..."
|
|
141
|
+
|
|
142
|
+
# Or
|
|
143
|
+
|
|
144
|
+
solution.g_recaptcha_response # Deprecated
|
|
145
|
+
"P0_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXNza2V5IjoiNnpWV..."
|
|
146
|
+
```
|
|
130
147
|
|
|
131
|
-
|
|
132
|
-
identify the website in which the CAPTCHA is found.
|
|
148
|
+
*Parameters:*
|
|
133
149
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
150
|
+
- `website_key`: the site key for the hCatpcha.
|
|
151
|
+
- `website_url`: the URL of the page with the hCaptcha challenge.
|
|
152
|
+
- `proxy_type`: optional parameter. Proxy connection protocol.
|
|
153
|
+
- `proxy_address`: optional parameter. The proxy address.
|
|
154
|
+
- `proxy_port`: optional parameter. The proxy port.
|
|
155
|
+
- `proxy_login`: optional parameter. The proxy login.
|
|
156
|
+
- `proxy_password`: optional parameter. The proxy password.
|
|
157
|
+
- `user_agent`: optional parameter. The user agent.
|
|
140
158
|
|
|
141
|
-
|
|
142
|
-
solution.token # Solution of the captcha
|
|
143
|
-
```
|
|
159
|
+
#### FunCaptcha
|
|
144
160
|
|
|
145
|
-
|
|
161
|
+
```ruby
|
|
162
|
+
solution = client.decode_fun_captcha!(
|
|
163
|
+
website_public_key: 'xyz',
|
|
164
|
+
website_url: 'http://example.com/example=1',
|
|
165
|
+
# proxy_type: 'http', # OPTIONAL
|
|
166
|
+
# proxy_address: '127.0.0.1', # OPTIONAL
|
|
167
|
+
# proxy_port: '8080', # OPTIONAL
|
|
168
|
+
# proxy_login: 'proxyLoginHere', # OPTIONAL
|
|
169
|
+
# proxy_password: 'proxyPasswordHere', # OPTIONAL
|
|
170
|
+
# user_agent: 'MODERN_USER_AGENT_HERE', # OPTIONAL
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
solution.token
|
|
174
|
+
"380633616d817f2b8.2351188603|r=ap-southeast-2|met..."
|
|
175
|
+
```
|
|
146
176
|
|
|
147
|
-
|
|
177
|
+
*Parameters:*
|
|
148
178
|
|
|
149
|
-
|
|
179
|
+
- `website_key`: the site key for the hCatpcha.
|
|
180
|
+
- `website_url`: the URL of the page with the hCaptcha challenge.
|
|
181
|
+
- `proxy_type`: optional parameter. Proxy connection protocol.
|
|
182
|
+
- `proxy_address`: optional parameter. The proxy address.
|
|
183
|
+
- `proxy_port`: optional parameter. The proxy port.
|
|
184
|
+
- `proxy_login`: optional parameter. The proxy login.
|
|
185
|
+
- `proxy_password`: optional parameter. The proxy password.
|
|
186
|
+
- `user_agent`: optional parameter. The user agent.
|
|
150
187
|
|
|
151
|
-
|
|
152
|
-
- `decode_recaptcha_v3!`: solves reCAPTCHA v3. It may raise an `AntiCaptcha::Error` if something goes wrong.
|
|
188
|
+
#### Geetest
|
|
153
189
|
|
|
154
|
-
|
|
190
|
+
```ruby
|
|
191
|
+
solution = client.decode_geetest!(
|
|
192
|
+
website_url: 'http://mywebsite.com/geetest/test.php',
|
|
193
|
+
gt: '874703612e5cac182812a00e273aad0d',
|
|
194
|
+
challenge: 'a559b82bca2c500101a1c8a4f4204742',
|
|
195
|
+
# proxy_type: 'http', # OPTIONAL
|
|
196
|
+
# proxy_address: '127.0.0.1', # OPTIONAL
|
|
197
|
+
# proxy_port: '8080', # OPTIONAL
|
|
198
|
+
# proxy_login: 'proxyLoginHere', # OPTIONAL
|
|
199
|
+
# proxy_password: 'proxyPasswordHere', # OPTIONAL
|
|
200
|
+
# user_agent: 'MODERN_USER_AGENT_HERE', # OPTIONAL
|
|
201
|
+
)
|
|
155
202
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
desire.
|
|
203
|
+
solution.v3['challenge']
|
|
204
|
+
"3c1c5153aa48011e92883aed820069f3hj"
|
|
159
205
|
|
|
160
|
-
|
|
206
|
+
solution.v3['validate']
|
|
207
|
+
"47ad5a0a6eb98a95b2bcd9e9eecc8272"
|
|
161
208
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
website_key: 'xyz',
|
|
165
|
-
website_url: 'http://example.com/example=1',
|
|
166
|
-
min_score: 0.3,
|
|
167
|
-
page_action: 'myverify'
|
|
168
|
-
}
|
|
209
|
+
solution.v3['seccode']
|
|
210
|
+
"83fa4f2d23005fc91c3a015a1613f803|jordan"
|
|
169
211
|
|
|
170
|
-
|
|
171
|
-
solution.g_recaptcha_response # Solution of the captcha
|
|
172
|
-
```
|
|
212
|
+
# Or
|
|
173
213
|
|
|
174
|
-
|
|
175
|
-
|
|
214
|
+
solution.v4['captcha_id']
|
|
215
|
+
"fcd636b4514bf7ac4143922550b3008b"
|
|
176
216
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
```
|
|
217
|
+
solution.v4['lot_number']
|
|
218
|
+
"354ab6dd4e594fdc903074c4d8d37b24"
|
|
180
219
|
|
|
181
|
-
|
|
220
|
+
solution.v4['pass_token']
|
|
221
|
+
"b645946a654e60218c7922b74b3b5ee8e8717e8fd3cd51..."
|
|
182
222
|
|
|
183
|
-
|
|
223
|
+
solution.v4['gen_time']
|
|
224
|
+
"1649921519"
|
|
184
225
|
|
|
185
|
-
|
|
226
|
+
solution.v4['captcha_output']
|
|
227
|
+
"cFPIALDXSop8Ri2mPABbRWzNBs86N8D4vNUTuVa7wN7E..."
|
|
228
|
+
```
|
|
229
|
+
*Parameters:*
|
|
230
|
+
|
|
231
|
+
- `website_url`: URL of a target web page. It can be located anywhere on the web site, even in a member's area.
|
|
232
|
+
- `gt`: the domain's public key.
|
|
233
|
+
- `challenge`: changing token key. Make sure you grab a fresh one for each captcha.
|
|
234
|
+
- `geetest_api_server_subdomain`: optional parameter. API subdomain. May be required for some implementations.
|
|
235
|
+
- `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.
|
|
236
|
+
- `version`: optional parameter. Version number. Default version is 3. Supported versions: 3 and 4.
|
|
237
|
+
- `init_parameters`: optional parameter. Additional initialization parameters for version 4.
|
|
238
|
+
- `proxy_type`: optional parameter. Proxy connection protocol.
|
|
239
|
+
- `proxy_address`: optional parameter. The proxy address.
|
|
240
|
+
- `proxy_port`: optional parameter. The proxy port.
|
|
241
|
+
- `proxy_login`: optional parameter. The proxy login.
|
|
242
|
+
- `proxy_password`: optional parameter. The proxy password.
|
|
243
|
+
- `user_agent`: optional parameter. The user agent.
|
|
244
|
+
|
|
245
|
+
### 3. Report an incorrectly solved image CAPTCHA for a refund
|
|
246
|
+
|
|
247
|
+
It is only possible to report incorrectly solved image CAPTCHAs.
|
|
186
248
|
|
|
187
|
-
|
|
188
|
-
|
|
249
|
+
```ruby
|
|
250
|
+
client.report_incorrect_image_catpcha!(task_id)
|
|
251
|
+
```
|
|
189
252
|
|
|
190
|
-
|
|
253
|
+
### 4. Get your account balance
|
|
191
254
|
|
|
192
|
-
|
|
193
|
-
|
|
255
|
+
```ruby
|
|
256
|
+
client.get_balance!
|
|
257
|
+
```
|
|
194
258
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
259
|
+
### 5. Get current stats of a queue.
|
|
260
|
+
|
|
261
|
+
Queue IDs:
|
|
262
|
+
|
|
263
|
+
- `1` Standart ImageToText, English language
|
|
264
|
+
- `2` Standart ImageToText, Russian language
|
|
265
|
+
- `5` Recaptcha NoCaptcha tasks
|
|
266
|
+
- `6` Recaptcha Proxyless task
|
|
267
|
+
- `7` Funcaptcha task
|
|
268
|
+
- `10` Funcaptcha Proxyless task
|
|
269
|
+
- `12` GeeTest with proxy
|
|
270
|
+
- `13` GeeTest without proxy
|
|
271
|
+
- `18` Recaptcha V3 s0.3
|
|
272
|
+
- `19` Recaptcha V3 s0.7
|
|
273
|
+
- `20` Recaptcha V3 s0.9
|
|
274
|
+
- `21` hCaptcha with proxy
|
|
275
|
+
- `22` hCaptcha without proxy
|
|
276
|
+
- `23` Recaptcha Enterprise V2 with proxy
|
|
277
|
+
- `24` Recaptcha Enterprise V2 without proxy
|
|
278
|
+
- `25` AntiGateTask
|
|
200
279
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
280
|
+
```ruby
|
|
281
|
+
client.get_queue_stats!(queue_id)
|
|
282
|
+
```
|
|
204
283
|
|
|
205
284
|
## Notes
|
|
206
285
|
|
|
207
|
-
|
|
286
|
+
### Ruby dependencies
|
|
208
287
|
|
|
209
288
|
AntiCaptcha doesn't require specific dependencies. That saves you memory and
|
|
210
289
|
avoid conflicts with other gems.
|
|
211
290
|
|
|
212
|
-
|
|
291
|
+
### Input image format
|
|
213
292
|
|
|
214
|
-
Any format you use in the
|
|
215
|
-
be converted to a body64
|
|
216
|
-
already have this format
|
|
217
|
-
|
|
293
|
+
Any format you use in the `decode_image!` method (`file`, `path`, `body`, `body64`)
|
|
294
|
+
will always be converted to a `body64`, which is a base64-encoded binary string.
|
|
295
|
+
So, if you already have this format on your end, there is no need for convertions
|
|
296
|
+
before calling the API.
|
|
218
297
|
|
|
219
298
|
> Our recomendation is to never convert your image format, unless needed. Let
|
|
220
299
|
> the gem convert internally. It may save you resources (CPU, memory and IO).
|
|
221
300
|
|
|
222
|
-
|
|
301
|
+
### Versioning
|
|
223
302
|
|
|
224
303
|
AntiCaptcha gem uses [Semantic Versioning](http://semver.org/).
|
|
225
304
|
|
|
226
305
|
# License
|
|
227
306
|
|
|
228
|
-
MIT License. Copyright (C) 2011-
|
|
307
|
+
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)
|
|
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,47 @@ 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
|
+
|
|
206
249
|
# Creates a task for solving the selected CAPTCHA type.
|
|
207
250
|
#
|
|
208
251
|
# @param [String] type The type of the CAPTCHA.
|
|
@@ -262,9 +305,9 @@ module AntiCaptcha
|
|
|
262
305
|
comment: options[:comment],
|
|
263
306
|
}
|
|
264
307
|
|
|
265
|
-
when '
|
|
308
|
+
when 'RecaptchaV2Task'
|
|
266
309
|
args[:task] = {
|
|
267
|
-
type: '
|
|
310
|
+
type: 'RecaptchaV2Task',
|
|
268
311
|
websiteURL: options[:website_url],
|
|
269
312
|
websiteKey: options[:website_key],
|
|
270
313
|
}
|
|
@@ -272,11 +315,13 @@ module AntiCaptcha
|
|
|
272
315
|
when 'RecaptchaV3TaskProxyless'
|
|
273
316
|
args[:task] = {
|
|
274
317
|
type: 'RecaptchaV3TaskProxyless',
|
|
275
|
-
websiteURL:
|
|
276
|
-
websiteKey:
|
|
277
|
-
minScore:
|
|
278
|
-
pageAction:
|
|
318
|
+
websiteURL: options[:website_url],
|
|
319
|
+
websiteKey: options[:website_key],
|
|
320
|
+
minScore: (options[:min_score] || 0.3).to_f,
|
|
321
|
+
pageAction: options[:page_action],
|
|
279
322
|
}
|
|
323
|
+
args[:isEnterprise] = options[:is_enterprise] if [true, false].include?(options[:is_enterprise])
|
|
324
|
+
|
|
280
325
|
|
|
281
326
|
when 'FunCaptchaTask'
|
|
282
327
|
args[:task] = {
|
|
@@ -287,14 +332,25 @@ module AntiCaptcha
|
|
|
287
332
|
|
|
288
333
|
when 'HCaptchaTask'
|
|
289
334
|
args[:task] = {
|
|
290
|
-
type:
|
|
335
|
+
type: 'HCaptchaTask',
|
|
291
336
|
websiteURL: options[:website_url],
|
|
292
337
|
websiteKey: options[:website_key],
|
|
293
338
|
}
|
|
294
339
|
|
|
340
|
+
when 'GeeTestTask'
|
|
341
|
+
args[:task] = {
|
|
342
|
+
type: 'GeeTestTask',
|
|
343
|
+
websiteURL: options[:website_url],
|
|
344
|
+
gt: options[:gt],
|
|
345
|
+
challenge: options[:challenge],
|
|
346
|
+
}
|
|
347
|
+
args[:geetestApiServerSubdomain] = options[:geetest_api_server_subdomain] if !options[:geetest_api_server_subdomain].nil?
|
|
348
|
+
args[:geetestGetLib] = options[:geetest_get_lib] if !options[:geetest_get_lib].nil?
|
|
349
|
+
args[:version] = options[:version] if !options[:version].nil?
|
|
350
|
+
args[:initParameters] = options[:init_parameters] if !options[:init_parameters].nil?
|
|
351
|
+
|
|
295
352
|
else
|
|
296
|
-
message = "Invalid task type: '#{type}'.
|
|
297
|
-
"#{SUPPORTED_TASKS.join(', ')}"
|
|
353
|
+
message = "Invalid task type: '#{type}'."
|
|
298
354
|
raise AntiCaptcha::ArgumentError.new(message)
|
|
299
355
|
end
|
|
300
356
|
|
|
@@ -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,11 @@ 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'
|
|
40
41
|
require 'anti_captcha/models/task_result'
|
|
41
42
|
require 'anti_captcha/client'
|
|
42
43
|
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.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Infosimples
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-09-30 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,9 +75,10 @@ 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
|
|
@@ -86,7 +87,7 @@ homepage: https://github.com/infosimples/anti_captcha
|
|
|
86
87
|
licenses:
|
|
87
88
|
- MIT
|
|
88
89
|
metadata: {}
|
|
89
|
-
post_install_message:
|
|
90
|
+
post_install_message:
|
|
90
91
|
rdoc_options: []
|
|
91
92
|
require_paths:
|
|
92
93
|
- lib
|
|
@@ -101,8 +102,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
101
102
|
- !ruby/object:Gem::Version
|
|
102
103
|
version: '0'
|
|
103
104
|
requirements: []
|
|
104
|
-
rubygems_version: 3.
|
|
105
|
-
signing_key:
|
|
105
|
+
rubygems_version: 3.1.4
|
|
106
|
+
signing_key:
|
|
106
107
|
specification_version: 4
|
|
107
108
|
summary: Ruby API for Anti Captcha (CAPTCHA Solver as a Service)
|
|
108
109
|
test_files: []
|