yandex-smartcaptcha-solver 1.0.0 → 1.0.1

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.
Files changed (2) hide show
  1. package/index.js +55 -25
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -3,6 +3,7 @@ const { v4: uuidv4 } = require('uuid');
3
3
  const FormData = require('form-data');
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
+ const { SocksProxyAgent } = require('socks-proxy-agent');
6
7
 
7
8
  /**
8
9
  * Yandex SmartCaptcha Solver
@@ -51,7 +52,7 @@ class YandexSmartCaptchaSolver {
51
52
  siteUrl: config.siteUrl,
52
53
  siteKey: config.siteKey,
53
54
  host: url.hostname,
54
- coreName: config.coreName || null, // Опциональное имя ядра
55
+ coreName: config.coreName || null,
55
56
 
56
57
  // Опции
57
58
  userAgent: options.userAgent || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
@@ -68,7 +69,17 @@ class YandexSmartCaptchaSolver {
68
69
  recognizedText: null
69
70
  };
70
71
 
71
- this.axios = axios.create({
72
+ if (this.config.saveImages && !fs.existsSync(this.config.imagesDir)) {
73
+ fs.mkdirSync(this.config.imagesDir, { recursive: true });
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Создать axios инстанс с опциональным прокси
79
+ * @private
80
+ */
81
+ _createAxiosInstance(proxy = null) {
82
+ const axiosConfig = {
72
83
  headers: {
73
84
  'User-Agent': this.config.userAgent,
74
85
  'Accept': '*/*',
@@ -76,11 +87,22 @@ class YandexSmartCaptchaSolver {
76
87
  'Accept-Encoding': 'gzip, deflate, br'
77
88
  },
78
89
  timeout: this.config.timeout
79
- });
90
+ };
80
91
 
81
- if (this.config.saveImages && !fs.existsSync(this.config.imagesDir)) {
82
- fs.mkdirSync(this.config.imagesDir, { recursive: true });
92
+ // Добавляем прокси агент, если указан
93
+ if (proxy) {
94
+ const proxyUrl = proxy.username && proxy.password
95
+ ? `socks5://${proxy.username}:${proxy.password}@${proxy.host}:${proxy.port}`
96
+ : `socks5://${proxy.host}:${proxy.port}`;
97
+
98
+ const proxyAgent = new SocksProxyAgent(proxyUrl);
99
+ axiosConfig.httpAgent = proxyAgent;
100
+ axiosConfig.httpsAgent = proxyAgent;
101
+
102
+ this._log(`Using SOCKS5 proxy: ${proxy.host}:${proxy.port}`, 'info');
83
103
  }
104
+
105
+ return axios.create(axiosConfig);
84
106
  }
85
107
 
86
108
  /**
@@ -146,7 +168,7 @@ class YandexSmartCaptchaSolver {
146
168
  * Первый запрос к Yandex SmartCaptcha
147
169
  * @private
148
170
  */
149
- async _firstCheck() {
171
+ async _firstCheck(axiosInstance) {
150
172
  this._log('Performing first check request...', 'debug');
151
173
 
152
174
  const url = `https://smartcaptcha.yandexcloud.net/check?host=${this.config.host}&sitekey=${this.config.siteKey}&href=${encodeURIComponent(this.config.siteUrl)}`;
@@ -161,7 +183,7 @@ class YandexSmartCaptchaSolver {
161
183
  'Sec-Fetch-Site': 'same-origin'
162
184
  };
163
185
 
164
- const response = await this.axios.post(url, data, { headers });
186
+ const response = await axiosInstance.post(url, data, { headers });
165
187
  return response.data;
166
188
  }
167
189
 
@@ -169,7 +191,7 @@ class YandexSmartCaptchaSolver {
169
191
  * Второй запрос к Yandex SmartCaptcha
170
192
  * @private
171
193
  */
172
- async _secondCheck(captchaKey) {
194
+ async _secondCheck(captchaKey, axiosInstance) {
173
195
  this._log('Performing second check request...', 'debug');
174
196
 
175
197
  const url = `https://smartcaptcha.yandexcloud.net/check?host=${this.config.host}&sitekey=${this.config.siteKey}&href=${encodeURIComponent(this.config.siteUrl)}`;
@@ -183,7 +205,7 @@ class YandexSmartCaptchaSolver {
183
205
  'Sec-Fetch-Site': 'same-origin'
184
206
  };
185
207
 
186
- const response = await this.axios.post(url, data, { headers });
208
+ const response = await axiosInstance.post(url, data, { headers });
187
209
  return response.data;
188
210
  }
189
211
 
@@ -191,10 +213,10 @@ class YandexSmartCaptchaSolver {
191
213
  * Получить изображение капчи
192
214
  * @private
193
215
  */
194
- async _getImage(imageUrl) {
216
+ async _getImage(imageUrl, axiosInstance) {
195
217
  this._log('Downloading captcha image...', 'debug');
196
218
 
197
- const response = await this.axios.get(imageUrl, {
219
+ const response = await axiosInstance.get(imageUrl, {
198
220
  responseType: 'arraybuffer',
199
221
  headers: {
200
222
  'Referer': 'https://smartcaptcha.yandexcloud.net/'
@@ -298,7 +320,7 @@ class YandexSmartCaptchaSolver {
298
320
  * Отправить результат в Yandex
299
321
  * @private
300
322
  */
301
- async _submit(captchaKey, encodedResult) {
323
+ async _submit(captchaKey, encodedResult, axiosInstance) {
302
324
  this._log('Submitting answer to Yandex...', 'info');
303
325
 
304
326
  // Задержка для имитации человека
@@ -318,37 +340,45 @@ class YandexSmartCaptchaSolver {
318
340
  'Sec-Fetch-Site': 'same-origin'
319
341
  };
320
342
 
321
- const response = await this.axios.post(url, data, { headers });
343
+ const response = await axiosInstance.post(url, data, { headers });
322
344
  return response.data;
323
345
  }
324
346
 
325
347
  /**
326
348
  * Решить капчу
349
+ * @param {Object} [proxy] - Настройки SOCKS5 прокси (опционально)
350
+ * @param {string} [proxy.host] - Хост прокси (например: '127.0.0.1')
351
+ * @param {number} [proxy.port] - Порт прокси (например: 1080)
352
+ * @param {string} [proxy.username] - Логин для прокси (опционально)
353
+ * @param {string} [proxy.password] - Пароль для прокси (опционально)
327
354
  * @returns {Promise<Object>} Результат с полями status и token (spravka)
328
355
  * @throws {Error} При неудаче
329
356
  * @example
330
- * const result = await solver.solve();
357
+ * const result = await solver.solve({ host: '127.0.0.1', port: 1080 });
331
358
  * console.log(result); // { status: 'ok', token: 'dD0x...' }
332
359
  */
333
- async solve() {
360
+ async solve(proxy = null) {
334
361
  let imageBuffer = null;
335
362
 
336
363
  try {
337
364
  this._log('Starting captcha solving process...', 'info');
338
365
 
366
+ // Создаем axios инстанс с прокси
367
+ const axiosInstance = this._createAxiosInstance(proxy);
368
+
339
369
  // Генерируем GUID
340
370
  const guid = uuidv4();
341
371
  this._log(`Generated GUID: ${guid}`, 'debug');
342
372
 
343
373
  // Первый запрос
344
- const firstResponse = await this._firstCheck();
374
+ const firstResponse = await this._firstCheck(axiosInstance);
345
375
  if (!firstResponse.captcha?.key) {
346
376
  throw new Error('No captcha key received from first request');
347
377
  }
348
378
  this._log('First captcha key received', 'debug');
349
379
 
350
380
  // Второй запрос
351
- const secondResponse = await this._secondCheck(firstResponse.captcha.key);
381
+ const secondResponse = await this._secondCheck(firstResponse.captcha.key, axiosInstance);
352
382
  if (!secondResponse.captcha?.image) {
353
383
  throw new Error('No captcha image URL received');
354
384
  }
@@ -357,23 +387,22 @@ class YandexSmartCaptchaSolver {
357
387
  this._log('Second captcha key received', 'debug');
358
388
 
359
389
  // Получаем и распознаем изображение
360
- imageBuffer = await this._getImage(secondResponse.captcha.image);
390
+ imageBuffer = await this._getImage(secondResponse.captcha.image, axiosInstance);
361
391
  const recognizedText = await this._recognize(imageBuffer);
362
392
 
363
393
  // Кодируем и отправляем
364
394
  const encodedResult = this._encode(recognizedText);
365
395
  this._log(`Encoded result: ${encodedResult}`, 'debug');
366
396
 
367
- const finalResponse = await this._submit(captchaKey, encodedResult);
397
+ const finalResponse = await this._submit(captchaKey, encodedResult, axiosInstance);
368
398
 
369
399
  // Проверяем результат
370
400
  if (finalResponse.status === 'ok') {
371
401
  this._log('Captcha solved successfully!', 'info');
372
402
  this._saveImage(imageBuffer, recognizedText, true);
373
-
374
403
  return {
375
404
  status: 'ok',
376
- token: finalResponse.token || finalResponse.key
405
+ token: finalResponse.spravka
377
406
  };
378
407
  } else {
379
408
  // Неудача - сообщаем XEvil
@@ -398,18 +427,19 @@ class YandexSmartCaptchaSolver {
398
427
  * Решить капчу с автоматическими повторными попытками
399
428
  * @param {number} [maxAttempts=3] - Максимальное количество попыток
400
429
  * @param {number} [retryDelay=3000] - Задержка между попытками (мс)
430
+ * @param {Object} [proxy] - Настройки SOCKS5 прокси (опционально)
401
431
  * @returns {Promise<Object>} Результат с полями status и token
402
432
  * @throws {Error} Если все попытки неудачны
403
433
  * @example
404
- * const result = await solver.solveWithRetry(5, 4000);
434
+ * const result = await solver.solveWithRetry(5, 4000, { host: '127.0.0.1', port: 1080 });
405
435
  */
406
- async solveWithRetry(maxAttempts = 3, retryDelay = 3000) {
436
+ async solveWithRetry(maxAttempts = 3, retryDelay = 3000, proxy = null) {
407
437
  this._log(`Will attempt to solve up to ${maxAttempts} times`, 'info');
408
438
 
409
439
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
410
440
  try {
411
441
  this._log(`Attempt ${attempt}/${maxAttempts}`, 'info');
412
- const result = await this.solve();
442
+ const result = await this.solve(proxy);
413
443
  this._log(`Successfully solved on attempt ${attempt}!`, 'info');
414
444
  return result;
415
445
  } catch (error) {
@@ -426,4 +456,4 @@ class YandexSmartCaptchaSolver {
426
456
  }
427
457
  }
428
458
 
429
- module.exports = YandexSmartCaptchaSolver;
459
+ module.exports = YandexSmartCaptchaSolver;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yandex-smartcaptcha-solver",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Automatic Yandex SmartCaptcha solver using XEvil OCR service",
5
5
  "main": "index.js",
6
6
  "scripts": {