Решение капч кликами на примере FunCaptcha и заработок на этом

volody00

Client
Joined
Sep 6, 2016
Messages
953
Reaction score
1,050
Points
93
115229
Есть несколько способов решения капч с помощью сервисов:
  • Токеном
  • Прокликиванием картинок
  • Через расширение
В этой статье мы с вами рассмотрим второй способ на примере FunCaptcha, т.к. именно с ней я наиболее плотно работал последние пару месяцев. Освоив принципы, изложенные в статье, вы также сможете написать решение для hcaptcha, recaptcha или любой другой капчи, которую можно решить кликами.

Что нам с вами нужно для успешного решения капчи:
  • Уметь читать документацию API сервисов для решения капч, составлять запросы и обрабатывать ответы
  • Уметь получать задание и картинку со страницы
Важно: я не буду тут выкладывать полностью готовое решение. Отладка и доведение до ума уже ложится на ваши плечи, если оно вам действительно нужно.

Разбираемся с составлением запросов

Весь процесс будем рассматривать на примере Capmonster.cloud. Освоив работу с ним, вы сможете работать и с любым другим сервисом по решению капч.

Первым делом заходим на страницу с описанием API. Для этого достаточно вбить в поисковик «API название сервиса». Для capmonster.cloud - https://zennolab.atlassian.net/wiki/spaces/APIS/pages/589825

По сути нам с вами нужно сделать всего два запроса:
  • Создать задачу
  • Получить результат решения
Почти во всех сервисах документация условно поделена на две части: как в принципе создавать запросы и что нужно заполнять при решении конкретной капчи. Т.е. нет одной страницы, где пошагово будет описано, как и что делать.

115203


Перейдем на страницу создания задачи и посмотрим, что там есть.

115204


1 – урл, куда надо отправлять запрос
2 – тип данных. Почти всегда это json
3 – какие параметры надо передавать.
4 – тип параметра. Если это string, то заключаем в двойные кавычки. Если написано «объект», значит внутрь него будут вложены другие параметры
5 – обязательный или нет. Если не передать обязательный параметр, мы получим ошибку.
6 – описание

Давайте сразу перейдем в PM и заполним кубик POST запроса
115205

115206


1-урл (https://api.capmonster.cloud/createTask)
2-тип данных. Т.к. у нас в документации было прописано json, мы прописываем application/json
3 – тело запроса в формате JSON. JSON – это текстовый формат обмена данными. Заполняется в фигурных скобках в формате {“ключ”:”значение”}. Обратите внимание, что task у нас объект, поэтому в качестве значения выступает другой объект (поэтому я поставил фигурные скобки, но пока не заполнил содержимое). Также обратите внимание на значение ключа clientkey – оно будет подставлено из переменной cfg_apikey
4 – переменная, куда ляжет ответ от сервиса capmonster.cloud.

Чтобы заполнить task, нам надо перейти на страницу с нужной капчей. В нашем случае это FunCaptcha. Но сначала небольшое отступление.

Recaptcha, hCaptcha, FunCaptcha можно решить двумя способами – токеном и кликами. В первом случае решение идет токеном, т.е. вам будет прислан ответ в «текстовом» виде, который вы самостоятельно должны вставить на страницу и отправить сайту. Во втором случае вы высылаете сервису картинку, а он говорит, куда вам надо кликнуть. Мы работаем с вариантом №2.

Название нужного нам способа ComplexImageTask - https://zennolab.atlassian.net/wiki/spaces/APIS/pages/2293497857/ComplexImageTask+Funcaptcha+Funcaptcha
115207


Обратите внимание на параметры imageUrls и imagesBase64. В данном случае нам на выбор дается один из двух вариантов: либо мы высылаем массив урл (которые ведут на изображения), либо сами картинки в формате base64. Мы будем пользоваться вариантом №2. Давайте перейдем в PM и заполним содержимое нашего task
C#:
{
  "clientKey": "{-Variable.cfg_apiKey-}",
  "task": {
    "type": "ComplexImageTask",
    "class": "funcaptcha",
    "imageUrls": [
      "{-Variable.images-}"
    ],
    "metadata": {
      "Task": "{-Variable.issue-}"
    }
  }
}
Давайте сразу создадим и кубик для получения результата:
115208



И не забудьте создать переменные, которые мы использовали в кубиках (нажимаем на плюсик): cfg_apiKey, images, issue, taskId.

Добываем задание и картинку

Достать эти данные можно двумя способами: через трафик и через содержимое страницы. Скорее всего вы будете работать именно с трафиком, но поначалу может быть сложновато, если раньше вы этого не делали.

В трафике отображаются все запросы, посылаемые браузером. Мы можем вытаскивать оттуда любые данные, в том числе и картинки. Давайте сначала потренируемся, а потом займемся уже капчей. Будем вытаскивать вот эту картинку и заголовок с сайта nashcsgo.com
115209



Включаем окно трафика

115210


Прописываем в кубике c# (выполняем это 1 раз перед началом работы с сайтом, чтобы не было проблем в zp)
C#:
instance.UseTrafficMonitoring = true;
Очищаем трафик, открываем devTools и вкладку NetWork, чтобы запросы также отображались и там тоже (помимо окна трафика) и переходим на сайт
115211

Выбираем img, чтобы отображались только картинки(1), жмём по любой картинке(2), выбираем preview, чтобы видеть сами картинки (3) и находим ту, что нам нужна.
115212


Жмём на Headers(1) и забираем урл картинки (2)
115213


Теперь отыщем наш заголовок. Для этого прям там же жмем ctrl+f и в появившемся окне вводим наш заголовок. Жмем enter
115214


Жмём на найденное совпадение (3). Жёлтым подчеркнут наш заголовок. Жмём на headers, чтобы забрать урл.

Теперь займёмся перебором всего трафика. Наша задача – выцепить два урл, которые мы с вами нашли и достать тело (т.е. то, что во вкладке response).

Сначала создайте две переменные - img_base64 для картинки и issue

переходим в кубик c#.
C#:
var traffic = instance.ActiveTab.GetTraffic();
project.SendInfoToLog($"количество запросов в трафике - {traffic.Count().ToString()}");
foreach (var t in traffic)
{
    //если в урл содержится images/skinsmin.jpg (картинка)
    if(t.Url.Contains("images/skinsmin.jpg"))
    {
        project.SendInfoToLog("нашли картинку");
   
        //дожидаемся полной прогрузки тела запроса
        t.WaitResponse(30, 2);
   
        //сохраняем в переменную "images" в формате base64 (создайте переменную вручную!)
        var imageBytes = t.ResponseBody;
        project.Variables["images"].Value = Convert.ToBase64String(imageBytes);
   
        //сохраняем на пк (этого делать не нужно, это просто для самопроверки)
        File.WriteAllBytes(project.Directory + @"\1.jpg", imageBytes);
   
    }

    //если урл равен https://nashcsgo.com/
    if(t.Url == "https://nashcsgo.com/")
    {
        project.SendInfoToLog("нашли заголовок");
        t.WaitResponse(30, 2);
   
        //сохраняем в переменную "issue" тело запроса
        var imageBytes = t.ResponseBody;
        project.Variables["issue"].Value = Encoding.UTF8.GetString(imageBytes, 0, imageBytes.Length);
    }
}

//проверка на пустоту и выход по ошибке
if(string.IsNullOrWhiteSpace(project.Variables["images"].Value)) throw new Exception("картинка не найдена");
if(string.IsNullOrWhiteSpace(project.Variables["issue"].Value)) throw new Exception("заголовок не найден");
Если вы всё сделали верно, то в переменной images у вас картинка в формате base64, в issue исходный код страницы (я уж не стал вычленять оттуда именно заголовок) и в папке проекта изображение 1.jpg (сохранил я её чисто для самопроверки, в рабочем проекте вы эту строчку убираете).

Хотел бы заострить ваше внимание на одном важном моменте – после того, как вы выполните этот код трафик будет очищен. Нет, визуально вы всё ещё будете его видеть, но если выполнить код ещё раз – то он уже не сработает. Важно держать это в голове.

Например, вы зашли на страницу с капчей. Запускаете код, что-то не работает, вы правите и снова запускаете – вообще всё перестает работать. Что за фигня? Просто трафик очистился. Вам нужно заново дойти до страницы с капчей и потом уже снова запустить свой код. Обход для этого есть, но там возникают другие проблемы и лучше просто смириться с подобным неудобством.

Так, если что-то непонятно, лучше проделайте всё сами, ну а мы перейдем уже к капче. Тут будем делать тоже самое (почти). Выставляем в настройках английский профиль, т.к. нам нужно отсылать задание именно на английском языке
115215



Перейдем на github.com и начнем процесс регистрации, пока не дойдем до капчи. Откройте также chromeDevTools и вкладку Network, чтобы мы могли отыскать картинку.
115218


Что мы здесь видим? Во-первых, нам отдаётся изображение целиком, так что никаких дополнительным манипуляций не нужно. Во-вторых, нам подходят два урл: rtig/image и blob. Нам нужен rtig/image. Почему? Потому что blob не отображается в мониторе трафика. Почему? Вопрос не ко мне.
115219


C#:
var traffic = instance.ActiveTab.GetTraffic();
project.Variables["images"].Value = "";
project.SendInfoToLog($"количество запросов в трафике - {traffic.Count().ToString()}");
foreach (var t in traffic)
{
    if(t.Url.Contains("rtig/image"))
    {
        project.SendInfoToLog("нашли картинку");
   
        t.WaitResponse(30, 2);
   
        var imageBytes = t.ResponseBody;
        project.Variables["images"].Value = Convert.ToBase64String(imageBytes);
   
        File.WriteAllBytes(project.Directory + @"\1.jpg", imageBytes);
   
    }
}

//проверка на пустоту и выход по ошибке
if(string.IsNullOrWhiteSpace(project.Variables["images"].Value)) throw new Exception("картинка не найдена");
С заголовком немного сложнее. Он есть в трафике, но я не смог его однозначно идентифицировать. Поэтому мы просто заберем его со страницы.
C#:
//находим элемент с заданием
var issue = instance.ActiveTab.FindElementByXPath("//*[@id='root']//h2/span", 0);
if(issue.IsVoid) throw new Exception(«не нашли задание на странице»);

//убираем <strong>, </strong>, (1 of *) и пробелы и сохр в переменную issue
string noStrong = issue.InnerHtml.Replace("<strong>", "").Replace("</strong>","").Trim();
project.Variables["issue"].Value = noStrong.Replace(Regex.Match(noStrong, @”\(.*\)).Value, @"").Trim();
project.SendInfoToLog("получили задание – " + project.Variables["issue"].Value);
А можно ли было картинку тоже вытащить из кода страницы, не прибегая к работе с трафиком? Можно, но некоторую сложность составляет то, что тут у нас blob изображения. Раньше я не знал как это сделать, но во время написания этой статьи наткнулся на способ. Сделать можно так (может кто предложит в комментариях решение без сохранения картинки на пк?)
C#:
//достаем наш урл
var imgBlob = instance.ActiveTab.FindElementByXPath("//img[@aria-live='assertive']", 0);
if(imgBlob.IsVoid) throw new Exception("не нашли картинку");
string styleBlob = imgBlob.GetAttribute("style");
string linkBlob = Regex.Match(styleBlob, @"blob:.*(?="")").Value;
if(string.IsNullOrWhiteSpace(linkBlob)) throw new Exception("не смогли достать урл картинки регуляркой");

//открываем в новой вкладке
instance.NewTab("1");
instance.ActiveTab.Navigate(linkBlob);
instance.ActiveTab.WaitDownloading();
Thread.Sleep(1000);

//сохраняем на пк
Bitmap b = new Bitmap(instance.ActiveTab.FindElementByXPath("//img", 0).DrawAsBitmap(true));
b.Save(project.Directory + @"\1.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
b.Dispose();

//считываем с пк
byte[] massByte = File.ReadAllBytes(project.Directory + @"\1.jpg");
string base64 = Convert.ToBase64String(massByte);
return base64;
Отправка на распознование и получение результата

Зайдите в личный кабинет capmonster.cloud, скопируйте ключ и вставьте в переменную cfg_apikey
115220


Теперь у нас есть всё необходимое для отправки на сервис capmonster.cloud. Выполняем наш кубик create и смотрим, что нам прислали в ответ. Чтобы проверить, найдите запрос в трафике, нажмите по нему два раза мышкой и перейдите на вкладку ответ. Если там error id=0, значит всё ок
115221

Сделаем проверку на то, что errorId == 0. Если это не так, то выйдем по ошибке и выведем сообщение в лог. Я делаю регулярками (это неправильно, но мне так привычнее), вы можете делать как вам удобно (с помощью кубика json)
115222

errorId\":0



Достаем taskId из ответа и кладем в переменную taskId. Ставим паузу в 1 сек и делаем запрос на получение ответа.

(?<="taskId":)\d+

Тут вы можете получить следующие ответы:
  • Ready – капча решена
  • Processing – в процессе решения
  • ERROR_CAPTCHA_UNSOLVABLE – сервис не может решить капчу
115224

Нам нужно сделать обработку для всех трех вариантов (если непонятно сделайте себе на кубиках).
C#:
//проверяем на ERROR_CAPTCHA_UNSOLVABLE
string errorUnsolvable = Regex.Match(project.Variables["getResult"].Value, @"ERROR_CAPTCHA_UNSOLVABLE").Value;
if(!string.IsNullOrWhiteSpace(errorUnsolvable)) throw new Exception("ERROR_CAPTCHA_UNSOLVABLE");


//проверяем статус
string status = Regex.Match(project.Variables["getResult"].Value, @"(?<=status"":"").*?(?="")").Value;
if(string.IsNullOrEmpty(status)) throw new Exception("не смогли извлечь status из ответа - " + project.Variables["getResult"].Value);

switch(status)
{
    //получили processing
    case "processing":
        project.SendInfoToLog("капча в процессе решения");
        project.Variables["statusSolution"].Value = "processing";
        break;
    //получили ready
    case "ready":
        project.SendInfoToLog("капча решена");
        project.Variables["statusSolution"].Value = "ready";
        break;
    default:
        throw new Exception("не смогли определить статус (не processing и не ready) - " + status);
}
115226

Сразу скажу, что ERROR_CAPTCHA_UNSOLVABLE не так, чтобы редкое явление. Тяжелые задания сервисы вообще не решают и не будут решать. Легкими заданиями считаются те, где нужно повернуть что-то в направлении руки и самих вариантов не больше 5. Ещё недавно это были животные и capmonster.cloud успешно их решал, но сейчас, как видим, картинки обновили и capmonster.cloud с ними не справляется. Возможно, на момент выхода статьи нейросеть уже будет обучена и сможет решать такие задания.

Чтобы попадались легкие задания используйте хорошие прокси и движок хромиум.

Так что далее вам придется поверить мне на слово. Вам придет ответ такого вида:
{"solution":{"answer":[false,false,false,false,false,true],"metadata":null},"cost":0.00015,"status":"ready","errorId":0,"errorCode":null,"errorDescription":null}
Там где true – это нужная нам картинка. Соответственно, нам надо с вами посчитать, какая она. После этого жмем по стрелке нужное количество раз и отправляем ответ.
C#:
//узнаем сколько раз надо кликнуть по стрелке
project.Json.FromString(project.Variables["getResult"].Value);
var otv = project.Json.solution.answer.ToString().Split(',');
string countClickCapmonster = Convert.ToString(otv.Length - 1);
if(string.IsNullOrWhiteSpace(countClickCapmonster)) throw new Exception("не смогли получить сколько раз надо кликать по стрелке вправо CapmonsterCloud");
project.SendInfoToLog($"нужно кликнуть {countClickCapmonster} раз");

//находим стрелку вправо
HtmlElement rightArrow = instance.ActiveTab.FindElementByXPath("(//a/*/*[name()='circle']/following-sibling::*)[last()]|(//a/*/*[name()='circle'])[last()]", 0);
if(rightArrow.IsVoid) throw new Exception("не найдена стрелка для переключения картинок");

//щелкаем нужное количество раз
for(int i=0;i<Convert.ToInt32(countClickCapmonster);i++)
{
    rightArrow.Click();
    Thread.Sleep(1000);
}

//жмем submit
var buttonSubmit = instance.ActiveTab.FindElementByXPath("//button[text()='Submit']", 0);
if(buttonSubmit.IsVoid) throw new Exception("не найдена кнопка submit");
buttonSubmit.Click();
Thread.Sleep(3000);
project.SendInfoToLog("нажали на нужное изображение");
Теперь надо определить есть ли ещё задания. Если да, то снова ищем картинку в трафике и отправляем на сервис. Если нет, тогда определяем, успешно ли мы решили капчу и действуем исходя из этого (если неудачно, можем попытаться снова или можно выйти по ошибке)
//если стрелка вправо есть, значит задания ещё есть
HtmlElement rightArrow = instance.ActiveTab.FindElementByXPath("(//a/*/*[name()='circle']/following-sibling::*)[last()]|(//a/*/*[name()='circle'])[last()]", 0);
if(!rightArrow.IsVoid)
{
    project.SendInfoToLog("задания ещё есть, продолжаем решать");
    project.Variables["status"].Value = "process";
    return "";
}

//решено неверно
HtmlElement notRight = instance.ActiveTab.FindElementByXPath("//h2[contains(text(), 'That was not quite right.')]", 0);
if(!notRight.IsVoid)
{
    project.SendInfoToLog("капча была решена неверно");
    project.Variables["status"].Value = "notRight";
    return "";
}

//галочка
var galka = instance.ActiveTab.FindElementByXPath("//img[contains(@src, 'thub-api.arkoselabs.com/cdn/fc/assets/style-manager/assets')]", 0);
if(!galka.IsVoid)
{
    project.SendInfoToLog("капча решена верно");
    project.Variables["status"].Value = "ready";
    return "";
}

//если не смогли опрелелить
project.Variables["status"].Value = "unknown";
Теперь надо определить есть ли ещё задания. Если да, то снова ищем картинку в трафике и отправляем на сервис. Если нет, тогда определяем, успешно ли мы решили капчу и действуем исходя из этого (если неудачно, можем попытаться снова или можно выйти по ошибке)
C#:
//если стрелка вправо есть, значит задания ещё есть
HtmlElement rightArrow = instance.ActiveTab.FindElementByXPath("(//a/*/*[name()='circle']/following-sibling::*)[last()]|(//a/*/*[name()='circle'])[last()]", 0);
if(!rightArrow.IsVoid)
{
    project.SendInfoToLog("задания ещё есть, продолжаем решать");
    project.Variables["status"].Value = "process";
    return "";
}

//решено неверно
HtmlElement notRight = instance.ActiveTab.FindElementByXPath("//h2[contains(text(), 'That was not quite right.')]", 0);
if(!notRight.IsVoid)
{
    project.SendInfoToLog("капча была решена неверно");
    project.Variables["status"].Value = "notRight";
    return "";
}

//галочка
var galka = instance.ActiveTab.FindElementByXPath("//img[contains(@src, 'thub-api.arkoselabs.com/cdn/fc/assets/style-manager/assets')]", 0);
if(!galka.IsVoid)
{
    project.SendInfoToLog("капча решена верно");
    project.Variables["status"].Value = "ready";
    return "";
}

//если не смогли опрелелить
project.Variables["status"].Value = "unknown";
Задания со стрелками попадаются чаще всего. Но также есть ещё задания, где надо выбрать одну из 6 картинок. Все делается аналогично, только надо будет кликать по нужному изображению, а не по стрелке. Эту часть я вам оставляю в качестве самостоятельной работы.

Заработок на решении капч
115232

5 октября я на форуме разместил тему о продаже плагина для решения FunCaptcha. За прошедшее время было 23 продажи на общую сумму 71 000 руб + было пара индивидуальных заказов. Размещался я только на этом форуме. Вроде бы неплохо, но есть несколько нюансов:
  • Не считая пары человек, взявших плагин на месяц, последняя продажа с форума была 6 ноября.
  • 15 продаж для меня сделал партнер, т.е. мне просто повезло. Человек предложил приводить клиентов за часть дохода, и я согласился. Если бы не он, у меня было бы всего 8 продаж.
Помимо дохода с продажи плагина удалось получить доход с партнерок капч (что явилось для меня полной неожиданностью). Если кто не в курсе, то большинство сервисов решения капч позволяют к запросам добавлять свой идентификатор и когда пользователь решает капчу, то вам падает небольшой процент.

Я тут ни на что не рассчитывал и добавил его больше по приколу. Какого же было моё удивление, когда я в один из дней увидел у себя на балансе $30. Поначалу я даже не мог врубиться, откуда они взялись и только потом до меня дошло, что я же размещал идентификатор. Сейчас у меня на балансе $130. Не так уж и плохо с 23 клиентов.

Вот тут lord_alfred поделился своими цифрами, можете также глянуть. У capmonster.cloud также есть партнерка, но нужно написать в саппорт, чтобы вам дали доступ. Так что этот вариант также не стоит списывать со счетов.

На этом всё. Для закрепления материала также можете посмотреть видео, где мы разбираемся с Recaptcha.

 
Номер конкурса статей
Двадцатый конкурс статей

Attachments

Для запуска проектов требуется программа ZennoPoster или ZennoDroid.
Это основное приложение, предназначенное для выполнения автоматизированных шаблонов действий (ботов).
Подробнее...

Для того чтобы запустить шаблон, откройте нужную программу. Нажмите кнопку «Добавить», и выберите файл проекта, который хотите запустить.
Подробнее о том, где и как выполняется проект.

Last edited by a moderator:

n0n3mi1y

Client
Joined
Mar 8, 2017
Messages
1,343
Reaction score
667
Points
113
Статья хорошая и описывает немало технических особенностей. Для себя подчеркнул момент с сохранением данных из элемента через конструктор Bitmap, спасибо.
Так как я тоже задумывался о освещении темы такого рода - как к этому отнеслись клиенты, которые оплатили решение, а вы потом выложили бесплатно это в конкурсную статью?
 
Last edited:

radv

Client
Joined
May 11, 2015
Messages
3,837
Reaction score
2,046
Points
113
Хороший пример по работе с такой капчей, :az: некоторые капчи проще решать кликами, чем другими способами.
 

volody00

Client
Joined
Sep 6, 2016
Messages
953
Reaction score
1,050
Points
93
Статья хорошая и описывает немало технических особенностей. Для себя подчеркнул момент с сохранением данных из элемента через конструктор Bitmap, спасибо.
Так как я тоже задумывался о освещении темы такого рода - как к этому отнеслись клиенты, которые оплатили решение, а вы потом выложили бесплатно это в конкурсную статью?
Да я же не выложил полностью готовое решение, это скорее заготовка. Не думаю, что из-за этого будут проблемы. Тут скорее ты мог бы отнестись негативно, если считаешь, что это как-то может повредить твоим продажам. А клиентов сейчас больше волнует, что вчера единственный сервис (на сколько я знаю), решающий токеном, "приказал долго жить".
 

n0n3mi1y

Client
Joined
Mar 8, 2017
Messages
1,343
Reaction score
667
Points
113
Да я же не выложил полностью готовое решение, это скорее заготовка. Не думаю, что из-за этого будут проблемы. Тут скорее ты мог бы отнестись негативно, если считаешь, что это как-то может повредить твоим продажам. А клиентов сейчас больше волнует, что вчера единственный сервис (на сколько я знаю), решающий токеном, "приказал долго жить".
Я всегда за здоровую конкуренцию) Это двигатель прогресса.
Сервис не единственный, есть альтернативы. Но не такие качественные, как были.
 
  • Thank you
Reactions: volody00

samsonnn

Client
Joined
Jun 2, 2015
Messages
1,858
Reaction score
1,580
Points
113
//открываем в новой вкладке instance.NewTab("1"); instance.ActiveTab.Navigate(linkBlob); instance.ActiveTab.WaitDownloading(); Thread.Sleep(1000); //сохраняем на пк Bitmap b = new Bitmap(instance.ActiveTab.FindElementByXPath("//img", 0).DrawAsBitmap(true)); b.Save(project.Directory + @"\1.jpg", System.Drawing.Imaging.ImageFormat.Jpeg); b.Dispose(); //считываем с пк byte[] massByte = File.ReadAllBytes(project.Directory + @"\1.jpg"); string base64 = Convert.ToBase64String(massByte); return base64;
серьезно? зачем такие сложности? почему сразу картинку в память не выгружаете?
 
  • Thank you
Reactions: Roman*

southside

Client
Joined
Apr 20, 2019
Messages
209
Reaction score
263
Points
63
Да я же не выложил полностью готовое решение, это скорее заготовка. Не думаю, что из-за этого будут проблемы. Тут скорее ты мог бы отнестись негативно, если считаешь, что это как-то может повредить твоим продажам. А клиентов сейчас больше волнует, что вчера единственный сервис (на сколько я знаю), решающий токеном, "приказал долго жить".
На них, кстати, майкрософт в суд подали (домен они же отжали), если кому интересно, можно ознакомиться, там очень интересное содержание
Короче все кто продает решения капчи Arkose - преступники :(
 
  • Thank you
Reactions: Roman*

samsonnn

Client
Joined
Jun 2, 2015
Messages
1,858
Reaction score
1,580
Points
113
Короче все кто продает решения капчи Arkose - преступники
Скоро и у меня будет свое решение через нейросеть, УКРФ мне пофиг :ds:
 
  • Thank you
Reactions: southside

radv

Client
Joined
May 11, 2015
Messages
3,837
Reaction score
2,046
Points
113

volody00

Client
Joined
Sep 6, 2016
Messages
953
Reaction score
1,050
Points
93
серьезно? зачем такие сложности? почему сразу картинку в память не выгружаете?
знаний не хватило. поделитесь кодом, это будет полезно
 

southside

Client
Joined
Apr 20, 2019
Messages
209
Reaction score
263
Points
63
Почему?
По мнению майкрософта :-)
"The Defendants are members of a criminal enterprise (hereinafter the “Fraudulent
Enterprise” or “Enterprise”) that uses lies and deception to breach Microsoft’s CAPTCHA and
other security measures" и тд
Это из пдфки суда. Вообще интересно, не помню, чтобы когда-либо сервисы капчи трогали таким вот образом
 

samsonnn

Client
Joined
Jun 2, 2015
Messages
1,858
Reaction score
1,580
Points
113
знаний не хватило. поделитесь кодом, это будет полезно
гугл не кто не отменял, и чат гпт тоже, я гуглил искал, проверял, а тебе готовое выдать? нет.
 

volody00

Client
Joined
Sep 6, 2016
Messages
953
Reaction score
1,050
Points
93
гугл не кто не отменял, и чат гпт тоже, я гуглил искал, проверял, а тебе готовое выдать? нет.
Я лишь привел пример, сам то я только с трафиком работаю. Меня всё устраивает, но возможно другим было бы полезно. Жаль, что вы не хотите внести свою лепту в эту статью, раз уж сами предложили улучшение. На этой ноте тему закроем, может кто-то другой напишет
 

Porosenok

Client
Joined
Sep 26, 2010
Messages
1,281
Reaction score
96
Points
48
Делал для себя такое же решение под рекапчу и фанкапчу. Не знал что это что-то настолько сложное и интересное что достойно написания статьи в конкурсе
 

volody00

Client
Joined
Sep 6, 2016
Messages
953
Reaction score
1,050
Points
93
Делал для себя такое же решение под рекапчу и фанкапчу. Не знал что это что-то настолько сложное и интересное что достойно написания статьи в конкурсе
Жаль, что чел с 13 летним опытом за всё это время не нашёл время и силы порадовать нас своими СЛОЖНЫМИ И ИНТЕРЕСНЫМИ материалами на конкурсе статей. Будем надеется, что к следующему конкурсу это изменится.
 
  • Thank you
Reactions: S10n4eg and rastvl

Ysocnet

Client
Joined
Sep 24, 2019
Messages
108
Reaction score
61
Points
28
Есть несколько способов решения капч с помощью сервисов:
  • Токеном
  • Прокликиванием картинок
  • Через расширение
В этой статье мы с вами рассмотрим второй способ на примере FunCaptcha, т.к. именно с ней я наиболее плотно работал последние пару месяцев. Освоив принципы, изложенные в статье, вы также сможете написать решение для hcaptcha, recaptcha или любой другой капчи, которую можно решить кликами.

Что нам с вами нужно для успешного решения капчи:
  • Уметь читать документацию API сервисов для решения капч, составлять запросы и обрабатывать ответы
  • Уметь получать задание и картинку со страницы
Важно: я не буду тут выкладывать полностью готовое решение. Отладка и доведение до ума уже ложится на ваши плечи, если оно вам действительно нужно.

Разбираемся с составлением запросов

Весь процесс будем рассматривать на примере Capmonster.cloud. Освоив работу с ним, вы сможете работать и с любым другим сервисом по решению капч.

Первым делом заходим на страницу с описанием API. Для этого достаточно вбить в поисковик «API название сервиса». Для capmonster.cloud - https://zennolab.atlassian.net/wiki/spaces/APIS/pages/589825

По сути нам с вами нужно сделать всего два запроса:
  • Создать задачу
  • Получить результат решения
Почти во всех сервисах документация условно поделена на две части: как в принципе создавать запросы и что нужно заполнять при решении конкретной капчи. Т.е. нет одной страницы, где пошагово будет описано, как и что делать.

View attachment 115203

Перейдем на страницу создания задачи и посмотрим, что там есть.

View attachment 115204

1 – урл, куда надо отправлять запрос
2 – тип данных. Почти всегда это json
3 – какие параметры надо передавать.
4 – тип параметра. Если это string, то заключаем в двойные кавычки. Если написано «объект», значит внутрь него будут вложены другие параметры
5 – обязательный или нет. Если не передать обязательный параметр, мы получим ошибку.
6 – описание

Давайте сразу перейдем в PM и заполним кубик POST запроса
View attachment 115205
View attachment 115206

1-урл (https://api.capmonster.cloud/createTask)
2-тип данных. Т.к. у нас в документации было прописано json, мы прописываем application/json
3 – тело запроса в формате JSON. JSON – это текстовый формат обмена данными. Заполняется в фигурных скобках в формате {“ключ”:”значение”}. Обратите внимание, что task у нас объект, поэтому в качестве значения выступает другой объект (поэтому я поставил фигурные скобки, но пока не заполнил содержимое). Также обратите внимание на значение ключа clientkey – оно будет подставлено из переменной cfg_apikey
4 – переменная, куда ляжет ответ от сервиса capmonster.cloud.

Чтобы заполнить task, нам надо перейти на страницу с нужной капчей. В нашем случае это FunCaptcha. Но сначала небольшое отступление.

Recaptcha, hCaptcha, FunCaptcha можно решить двумя способами – токеном и кликами. В первом случае решение идет токеном, т.е. вам будет прислан ответ в «текстовом» виде, который вы самостоятельно должны вставить на страницу и отправить сайту. Во втором случае вы высылаете сервису картинку, а он говорит, куда вам надо кликнуть. Мы работаем с вариантом №2.

Название нужного нам способа ComplexImageTask - https://zennolab.atlassian.net/wiki/spaces/APIS/pages/2293497857/ComplexImageTask+Funcaptcha+Funcaptcha
View attachment 115207

Обратите внимание на параметры imageUrls и imagesBase64. В данном случае нам на выбор дается один из двух вариантов: либо мы высылаем массив урл (которые ведут на изображения), либо сами картинки в формате base64. Мы будем пользоваться вариантом №2. Давайте перейдем в PM и заполним содержимое нашего task
C#:
{
  "clientKey": "{-Variable.cfg_apiKey-}",
  "task": {
    "type": "ComplexImageTask",
    "class": "funcaptcha",
    "imageUrls": [
      "{-Variable.images-}"
    ],
    "metadata": {
      "Task": "{-Variable.issue-}"
    }
  }
}
Давайте сразу создадим и кубик для получения результата:
View attachment 115208


И не забудьте создать переменные, которые мы использовали в кубиках (нажимаем на плюсик): cfg_apiKey, images, issue, taskId.

Добываем задание и картинку

Достать эти данные можно двумя способами: через трафик и через содержимое страницы. Скорее всего вы будете работать именно с трафиком, но поначалу может быть сложновато, если раньше вы этого не делали.

В трафике отображаются все запросы, посылаемые браузером. Мы можем вытаскивать оттуда любые данные, в том числе и картинки. Давайте сначала потренируемся, а потом займемся уже капчей. Будем вытаскивать вот эту картинку и заголовок с сайта nashcsgo.com
View attachment 115209


Включаем окно трафика

View attachment 115210

Прописываем в кубике c# (выполняем это 1 раз перед началом работы с сайтом, чтобы не было проблем в zp)
C#:
instance.UseTrafficMonitoring = true;
Очищаем трафик, открываем devTools и вкладку NetWork, чтобы запросы также отображались и там тоже (помимо окна трафика) и переходим на сайт
View attachment 115211
Выбираем img, чтобы отображались только картинки(1), жмём по любой картинке(2), выбираем preview, чтобы видеть сами картинки (3) и находим ту, что нам нужна.
View attachment 115212

Жмём на Headers(1) и забираем урл картинки (2)
View attachment 115213

Теперь отыщем наш заголовок. Для этого прям там же жмем ctrl+f и в появившемся окне вводим наш заголовок. Жмем enter
View attachment 115214

Жмём на найденное совпадение (3). Жёлтым подчеркнут наш заголовок. Жмём на headers, чтобы забрать урл.

Теперь займёмся перебором всего трафика. Наша задача – выцепить два урл, которые мы с вами нашли и достать тело (т.е. то, что во вкладке response).

Сначала создайте две переменные - img_base64 для картинки и issue

переходим в кубик c#.
C#:
var traffic = instance.ActiveTab.GetTraffic();
project.SendInfoToLog($"количество запросов в трафике - {traffic.Count().ToString()}");
foreach (var t in traffic)
{
    //если в урл содержится images/skinsmin.jpg (картинка)
    if(t.Url.Contains("images/skinsmin.jpg"))
    {
        project.SendInfoToLog("нашли картинку");
   
        //дожидаемся полной прогрузки тела запроса
        t.WaitResponse(30, 2);
   
        //сохраняем в переменную "images" в формате base64 (создайте переменную вручную!)
        var imageBytes = t.ResponseBody;
        project.Variables["images"].Value = Convert.ToBase64String(imageBytes);
   
        //сохраняем на пк (этого делать не нужно, это просто для самопроверки)
        File.WriteAllBytes(project.Directory + @"\1.jpg", imageBytes);
   
    }

    //если урл равен https://nashcsgo.com/
    if(t.Url == "https://nashcsgo.com/")
    {
        project.SendInfoToLog("нашли заголовок");
        t.WaitResponse(30, 2);
   
        //сохраняем в переменную "issue" тело запроса
        var imageBytes = t.ResponseBody;
        project.Variables["issue"].Value = Encoding.UTF8.GetString(imageBytes, 0, imageBytes.Length);
    }
}

//проверка на пустоту и выход по ошибке
if(string.IsNullOrWhiteSpace(project.Variables["images"].Value)) throw new Exception("картинка не найдена");
if(string.IsNullOrWhiteSpace(project.Variables["issue"].Value)) throw new Exception("заголовок не найден");
Если вы всё сделали верно, то в переменной images у вас картинка в формате base64, в issue исходный код страницы (я уж не стал вычленять оттуда именно заголовок) и в папке проекта изображение 1.jpg (сохранил я её чисто для самопроверки, в рабочем проекте вы эту строчку убираете).

Хотел бы заострить ваше внимание на одном важном моменте – после того, как вы выполните этот код трафик будет очищен. Нет, визуально вы всё ещё будете его видеть, но если выполнить код ещё раз – то он уже не сработает. Важно держать это в голове.

Например, вы зашли на страницу с капчей. Запускаете код, что-то не работает, вы правите и снова запускаете – вообще всё перестает работать. Что за фигня? Просто трафик очистился. Вам нужно заново дойти до страницы с капчей и потом уже снова запустить свой код. Обход для этого есть, но там возникают другие проблемы и лучше просто смириться с подобным неудобством.

Так, если что-то непонятно, лучше проделайте всё сами, ну а мы перейдем уже к капче. Тут будем делать тоже самое (почти). Выставляем в настройках английский профиль, т.к. нам нужно отсылать задание именно на английском языке
View attachment 115215


Перейдем на github.com и начнем процесс регистрации, пока не дойдем до капчи. Откройте также chromeDevTools и вкладку Network, чтобы мы могли отыскать картинку.
View attachment 115218

Что мы здесь видим? Во-первых, нам отдаётся изображение целиком, так что никаких дополнительным манипуляций не нужно. Во-вторых, нам подходят два урл: rtig/image и blob. Нам нужен rtig/image. Почему? Потому что blob не отображается в мониторе трафика. Почему? Вопрос не ко мне.
View attachment 115219

C#:
var traffic = instance.ActiveTab.GetTraffic();
project.Variables["images"].Value = "";
project.SendInfoToLog($"количество запросов в трафике - {traffic.Count().ToString()}");
foreach (var t in traffic)
{
    if(t.Url.Contains("rtig/image"))
    {
        project.SendInfoToLog("нашли картинку");
   
        t.WaitResponse(30, 2);
   
        var imageBytes = t.ResponseBody;
        project.Variables["images"].Value = Convert.ToBase64String(imageBytes);
   
        File.WriteAllBytes(project.Directory + @"\1.jpg", imageBytes);
   
    }
}

//проверка на пустоту и выход по ошибке
if(string.IsNullOrWhiteSpace(project.Variables["images"].Value)) throw new Exception("картинка не найдена");
С заголовком немного сложнее. Он есть в трафике, но я не смог его однозначно идентифицировать. Поэтому мы просто заберем его со страницы.
C#:
//находим элемент с заданием
var issue = instance.ActiveTab.FindElementByXPath("//*[@id='root']//h2/span", 0);
if(issue.IsVoid) throw new Exception(«не нашли задание на странице»);

//убираем <strong>, </strong>, (1 of *) и пробелы и сохр в переменную issue
string noStrong = issue.InnerHtml.Replace("<strong>", "").Replace("</strong>","").Trim();
project.Variables["issue"].Value = noStrong.Replace(Regex.Match(noStrong, @”\(.*\)).Value, @"").Trim();
project.SendInfoToLog("получили задание – " + project.Variables["issue"].Value);
А можно ли было картинку тоже вытащить из кода страницы, не прибегая к работе с трафиком? Можно, но некоторую сложность составляет то, что тут у нас blob изображения. Раньше я не знал как это сделать, но во время написания этой статьи наткнулся на способ. Сделать можно так (может кто предложит в комментариях решение без сохранения картинки на пк?)
C#:
//достаем наш урл
var imgBlob = instance.ActiveTab.FindElementByXPath("//img[@aria-live='assertive']", 0);
if(imgBlob.IsVoid) throw new Exception("не нашли картинку");
string styleBlob = imgBlob.GetAttribute("style");
string linkBlob = Regex.Match(styleBlob, @"blob:.*(?="")").Value;
if(string.IsNullOrWhiteSpace(linkBlob)) throw new Exception("не смогли достать урл картинки регуляркой");

//открываем в новой вкладке
instance.NewTab("1");
instance.ActiveTab.Navigate(linkBlob);
instance.ActiveTab.WaitDownloading();
Thread.Sleep(1000);

//сохраняем на пк
Bitmap b = new Bitmap(instance.ActiveTab.FindElementByXPath("//img", 0).DrawAsBitmap(true));
b.Save(project.Directory + @"\1.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
b.Dispose();

//считываем с пк
byte[] massByte = File.ReadAllBytes(project.Directory + @"\1.jpg");
string base64 = Convert.ToBase64String(massByte);
return base64;
Отправка на распознование и получение результата

Зайдите в личный кабинет capmonster.cloud, скопируйте ключ и вставьте в переменную cfg_apikey
View attachment 115220

Теперь у нас есть всё необходимое для отправки на сервис capmonster.cloud. Выполняем наш кубик create и смотрим, что нам прислали в ответ. Чтобы проверить, найдите запрос в трафике, нажмите по нему два раза мышкой и перейдите на вкладку ответ. Если там error id=0, значит всё ок
View attachment 115221
Сделаем проверку на то, что errorId == 0. Если это не так, то выйдем по ошибке и выведем сообщение в лог. Я делаю регулярками (это неправильно, но мне так привычнее), вы можете делать как вам удобно (с помощью кубика json)
View attachment 115222
errorId\":0



Достаем taskId из ответа и кладем в переменную taskId. Ставим паузу в 1 сек и делаем запрос на получение ответа.

(?<="taskId":)\d+

Тут вы можете получить следующие ответы:
  • Ready – капча решена
  • Processing – в процессе решения
  • ERROR_CAPTCHA_UNSOLVABLE – сервис не может решить капчу
View attachment 115224
Нам нужно сделать обработку для всех трех вариантов (если непонятно сделайте себе на кубиках).
C#:
//проверяем на ERROR_CAPTCHA_UNSOLVABLE
string errorUnsolvable = Regex.Match(project.Variables["getResult"].Value, @"ERROR_CAPTCHA_UNSOLVABLE").Value;
if(!string.IsNullOrWhiteSpace(errorUnsolvable)) throw new Exception("ERROR_CAPTCHA_UNSOLVABLE");


//проверяем статус
string status = Regex.Match(project.Variables["getResult"].Value, @"(?<=status"":"").*?(?="")").Value;
if(string.IsNullOrEmpty(status)) throw new Exception("не смогли извлечь status из ответа - " + project.Variables["getResult"].Value);

switch(status)
{
    //получили processing
    case "processing":
        project.SendInfoToLog("капча в процессе решения");
        project.Variables["statusSolution"].Value = "processing";
        break;
    //получили ready
    case "ready":
        project.SendInfoToLog("капча решена");
        project.Variables["statusSolution"].Value = "ready";
        break;
    default:
        throw new Exception("не смогли определить статус (не processing и не ready) - " + status);
}
View attachment 115226
Сразу скажу, что ERROR_CAPTCHA_UNSOLVABLE не так, чтобы редкое явление. Тяжелые задания сервисы вообще не решают и не будут решать. Легкими заданиями считаются те, где нужно повернуть что-то в направлении руки и самих вариантов не больше 5. Ещё недавно это были животные и capmonster.cloud успешно их решал, но сейчас, как видим, картинки обновили и capmonster.cloud с ними не справляется. Возможно, на момент выхода статьи нейросеть уже будет обучена и сможет решать такие задания.

Чтобы попадались легкие задания используйте хорошие прокси и движок хромиум.

Так что далее вам придется поверить мне на слово. Вам придет ответ такого вида:
{"solution":{"answer":[false,false,false,false,false,true],"metadata":null},"cost":0.00015,"status":"ready","errorId":0,"errorCode":null,"errorDescription":null}
Там где true – это нужная нам картинка. Соответственно, нам надо с вами посчитать, какая она. После этого жмем по стрелке нужное количество раз и отправляем ответ.
C#:
//узнаем сколько раз надо кликнуть по стрелке
project.Json.FromString(project.Variables["getResult"].Value);
var otv = project.Json.solution.answer.ToString().Split(',');
string countClickCapmonster = Convert.ToString(otv.Length - 1);
if(string.IsNullOrWhiteSpace(countClickCapmonster)) throw new Exception("не смогли получить сколько раз надо кликать по стрелке вправо CapmonsterCloud");
project.SendInfoToLog($"нужно кликнуть {countClickCapmonster} раз");

//находим стрелку вправо
HtmlElement rightArrow = instance.ActiveTab.FindElementByXPath("(//a/*/*[name()='circle']/following-sibling::*)[last()]|(//a/*/*[name()='circle'])[last()]", 0);
if(rightArrow.IsVoid) throw new Exception("не найдена стрелка для переключения картинок");

//щелкаем нужное количество раз
for(int i=0;i<Convert.ToInt32(countClickCapmonster);i++)
{
    rightArrow.Click();
    Thread.Sleep(1000);
}

//жмем submit
var buttonSubmit = instance.ActiveTab.FindElementByXPath("//button[text()='Submit']", 0);
if(buttonSubmit.IsVoid) throw new Exception("не найдена кнопка submit");
buttonSubmit.Click();
Thread.Sleep(3000);
project.SendInfoToLog("нажали на нужное изображение");
Теперь надо определить есть ли ещё задания. Если да, то снова ищем картинку в трафике и отправляем на сервис. Если нет, тогда определяем, успешно ли мы решили капчу и действуем исходя из этого (если неудачно, можем попытаться снова или можно выйти по ошибке)
//если стрелка вправо есть, значит задания ещё есть
HtmlElement rightArrow = instance.ActiveTab.FindElementByXPath("(//a/*/*[name()='circle']/following-sibling::*)[last()]|(//a/*/*[name()='circle'])[last()]", 0);
if(!rightArrow.IsVoid)
{
    project.SendInfoToLog("задания ещё есть, продолжаем решать");
    project.Variables["status"].Value = "process";
    return "";
}

//решено неверно
HtmlElement notRight = instance.ActiveTab.FindElementByXPath("//h2[contains(text(), 'That was not quite right.')]", 0);
if(!notRight.IsVoid)
{
    project.SendInfoToLog("капча была решена неверно");
    project.Variables["status"].Value = "notRight";
    return "";
}

//галочка
var galka = instance.ActiveTab.FindElementByXPath("//img[contains(@src, 'thub-api.arkoselabs.com/cdn/fc/assets/style-manager/assets')]", 0);
if(!galka.IsVoid)
{
    project.SendInfoToLog("капча решена верно");
    project.Variables["status"].Value = "ready";
    return "";
}

//если не смогли опрелелить
project.Variables["status"].Value = "unknown";
Теперь надо определить есть ли ещё задания. Если да, то снова ищем картинку в трафике и отправляем на сервис. Если нет, тогда определяем, успешно ли мы решили капчу и действуем исходя из этого (если неудачно, можем попытаться снова или можно выйти по ошибке)
C#:
//если стрелка вправо есть, значит задания ещё есть
HtmlElement rightArrow = instance.ActiveTab.FindElementByXPath("(//a/*/*[name()='circle']/following-sibling::*)[last()]|(//a/*/*[name()='circle'])[last()]", 0);
if(!rightArrow.IsVoid)
{
    project.SendInfoToLog("задания ещё есть, продолжаем решать");
    project.Variables["status"].Value = "process";
    return "";
}

//решено неверно
HtmlElement notRight = instance.ActiveTab.FindElementByXPath("//h2[contains(text(), 'That was not quite right.')]", 0);
if(!notRight.IsVoid)
{
    project.SendInfoToLog("капча была решена неверно");
    project.Variables["status"].Value = "notRight";
    return "";
}

//галочка
var galka = instance.ActiveTab.FindElementByXPath("//img[contains(@src, 'thub-api.arkoselabs.com/cdn/fc/assets/style-manager/assets')]", 0);
if(!galka.IsVoid)
{
    project.SendInfoToLog("капча решена верно");
    project.Variables["status"].Value = "ready";
    return "";
}

//если не смогли опрелелить
project.Variables["status"].Value = "unknown";
Задания со стрелками попадаются чаще всего. Но также есть ещё задания, где надо выбрать одну из 6 картинок. Все делается аналогично, только надо будет кликать по нужному изображению, а не по стрелке. Эту часть я вам оставляю в качестве самостоятельной работы.

Заработок на решении капч
View attachment 115232

5 октября я на форуме разместил тему о продаже плагина для решения FunCaptcha. За прошедшее время было 23 продажи на общую сумму 71 000 руб + было пара индивидуальных заказов. Размещался я только на этом форуме. Вроде бы неплохо, но есть несколько нюансов:
  • Не считая пары человек, взявших плагин на месяц, последняя продажа с форума была 6 ноября.
  • 15 продаж для меня сделал партнер, т.е. мне просто повезло. Человек предложил приводить клиентов за часть дохода, и я согласился. Если бы не он, у меня было бы всего 8 продаж.
Помимо дохода с продажи плагина удалось получить доход с партнерок капч (что явилось для меня полной неожиданностью). Если кто не в курсе, то большинство сервисов решения капч позволяют к запросам добавлять свой идентификатор и когда пользователь решает капчу, то вам падает небольшой процент.

Я тут ни на что не рассчитывал и добавил его больше по приколу. Какого же было моё удивление, когда я в один из дней увидел у себя на балансе $30. Поначалу я даже не мог врубиться, откуда они взялись и только потом до меня дошло, что я же размещал идентификатор. Сейчас у меня на балансе $130. Не так уж и плохо с 23 клиентов.

Вот тут lord_alfred поделился своими цифрами, можете также глянуть. У capmonster.cloud также есть партнерка, но нужно написать в саппорт, чтобы вам дали доступ. Так что этот вариант также не стоит списывать со счетов.

На этом всё. Для закрепления материала также можете посмотреть видео, где мы разбираемся с Recaptcha.

Видео - https://drive.google.com/file/d/1hRhAPWack-CiD1lUza3Up7UjFshBK_Yf/view?usp=sharing
Хорошая статья. Спасибо за проделанный труд и предоставленный материал
 
  • Thank you
Reactions: rastvl and volody00

rastvl

Client
Staff member
Joined
Jan 16, 2019
Messages
656
Reaction score
1,064
Points
93
Что мы здесь видим? Во-первых, нам отдаётся изображение целиком, так что никаких дополнительным манипуляций не нужно
У фанкапчи это не всегда так. На самом деле бывает по /image?challenge прилетает json с немного зашифрованными данными, которые нужно обработать определенным образом, чтобы получить картинку
нам подходят два урл: rtig/image и blob. Нам нужен rtig/image. Почему? Потому что blob не отображается в мониторе трафика. Почему? Вопрос не ко мне.
Тут согласен. Вопрос к разработчикам зенки) В трафике запрос виден, в "Protocol Monitor"(ctrl + F на странице) тоже, причём ответ там сразу в base64) Видимо, не ко всем фреймам ЗП цепляется. Может в восьмёрке лучше будет(Я не знаю)

Статья полезная, спасибо:dh::ay:. Но допускаю, новичкам с видео было бы понятнее)
 
  • Thank you
Reactions: volody00

rastvl

Client
Staff member
Joined
Jan 16, 2019
Messages
656
Reaction score
1,064
Points
93
Не знал что это что-то настолько сложное и интересное
А автор, как минимум, из-за допуска к конкурсу получит халявные обновы, потому что знал) И кто из вас тут больше шарит?)
 
  • Thank you
Reactions: Alexmd

volody00

Client
Joined
Sep 6, 2016
Messages
953
Reaction score
1,050
Points
93
У фанкапчи это не всегда так. На самом деле бывает по /image?challenge прилетает json с немного зашифрованными данными, которые нужно обработать определенным образом, чтобы получить картинку
Видел такое. Но на самом деле не обязательно эту картинку расшифровывать. Если такое встречается, картинку можно вытащить из урл начинающегося с blob. Если такого урл в трафике нет, то это сложное задание и сервисы его не решают (нет смысла доставать картинку).

К слову, если знаешь сервисы, решающие токеном Твиттер, напиши в ЛС (если не сложно), а то найти не получается. Спасибо
 

BAZAg

Client
Joined
Nov 8, 2015
Messages
1,798
Reaction score
2,483
Points
113
Сделать можно так (может кто предложит в комментариях решение без сохранения картинки на пк?)
C#:
//достаем наш урл
var imgBlob = instance.ActiveTab.FindElementByXPath("//img[@aria-live='assertive']", 0);
if(imgBlob.IsVoid) throw new Exception("не нашли картинку");
string styleBlob = imgBlob.GetAttribute("style");
string linkBlob = Regex.Match(styleBlob, @"blob:.*(?="")").Value;
if(string.IsNullOrWhiteSpace(linkBlob)) throw new Exception("не смогли достать урл картинки регуляркой");

//открываем в новой вкладке
instance.NewTab("1");
instance.ActiveTab.Navigate(linkBlob);
instance.ActiveTab.WaitDownloading();
Thread.Sleep(1000);

//сохраняем на пк
Bitmap b = new Bitmap(instance.ActiveTab.FindElementByXPath("//img", 0).DrawAsBitmap(true));
b.Save(project.Directory + @"\1.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
b.Dispose();

//считываем с пк
byte[] massByte = File.ReadAllBytes(project.Directory + @"\1.jpg");
string base64 = Convert.ToBase64String(massByte);
return base64;
Попробуй, может быть такое преобразование будет удобнее (без сохранения на диск):
C#:
string base64 ="";

using (var ms = new MemoryStream()) {   
    using (var b = new Bitmap(instance.ActiveTab.FindElementByXPath("//img", 0).DrawAsBitmap(true))) { 
        b.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
// b.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
        base64 = Convert.ToBase64String(ms.GetBuffer());
    }
}
 

FastSpace

Client
Read only
Joined
Apr 5, 2018
Messages
665
Reaction score
240
Points
43
У фанкапчи это не всегда так. На самом деле бывает по /image?challenge прилетает json с немного зашифрованными данными, которые нужно обработать определенным образом, чтобы получить картинку
У FunCaptha 6 видов каптч (известных мне), то что описал автор подойдет только к 3.
Например есть вид каптчи, где картинку таким способом не поймаешь, она спрятана в свойстве CSS.

Еще есть такой прикол (на амазон видел) тебе пикча приходит 450x300, а реальный размер ее в CSS 300x300. Ты пошлешь 450x300 тебе придут координаты которые не сопадут с 300x300
 
Last edited:

BAZAg

Client
Joined
Nov 8, 2015
Messages
1,798
Reaction score
2,483
Points
113
У FunCaptha 6 видов каптч (известных мне), то что описал автор подойдет только к 3.
Например есть вид каптчи, где картинку таким способом не поймаешь, она спрятана в свойстве CSS.
Разве автор где-то указал, что он подготовил комплексное решение, которое должно решать все виды FunCaptha?
С какими встречался и знает как с ними работать - об этом написал.
Что не знает - кто-то другой напишет в будущем.
 
  • Thank you
Reactions: Petr_G

FastSpace

Client
Read only
Joined
Apr 5, 2018
Messages
665
Reaction score
240
Points
43
Разве автор где-то указал, что он подготовил комплексное решение, которое должно решать все виды FunCaptha?
С какими встречался и знает как с ними работать - об этом написал.
Что не знает - кто-то другой напишет в будущем.
Я это говорил ежику, а не автору.
 

KiryaPerseus

Client
Joined
Oct 17, 2017
Messages
160
Reaction score
62
Points
28
Круто! Спасибо за статью, видел вашу тему с продажей плагина, недавно сам сел читать документацию Capmonstecloud API
И пилить решение фанкапчи, статья с кликиками помогла!)
 

bagzik

Client
Joined
Jul 16, 2013
Messages
6
Reaction score
5
Points
3
Спасибо большое за статью! Интересно было потестить решение капчи на гитхабе, а то я как-то пробовал написать авторегер аккаунтов github, но не смог побороть модуль с funcaptcha.

К сожалению и при тестировании этого шаблона не удается распознать капчпу((

Такая ошибка: {"errorId":1,"errorCode":"ERROR_CAPTCHA_UNSOLVABLE","errorDescription":"This type of captchas is not supported by the service or the image does not contain an answer, perhaps it is too noisy. It could also mean that the image is corrupted or was incorrectly rendered. "}
 

volody00

Client
Joined
Sep 6, 2016
Messages
953
Reaction score
1,050
Points
93
Спасибо большое за статью! Интересно было потестить решение капчи на гитхабе, а то я как-то пробовал написать авторегер аккаунтов github, но не смог побороть модуль с funcaptcha.

К сожалению и при тестировании этого шаблона не удается распознать капчпу((

Такая ошибка: {"errorId":1,"errorCode":"ERROR_CAPTCHA_UNSOLVABLE","errorDescription":"This type of captchas is not supported by the service or the image does not contain an answer, perhaps it is too noisy. It could also mean that the image is corrupted or was incorrectly rendered. "}
Ждите, пока capmonster.cloud переобучит свою нейросеть под новые задания
 
  • Thank you
Reactions: ZennoLab Team

softweri

Client
Joined
Mar 3, 2016
Messages
108
Reaction score
17
Points
18
А кто поделится таким на hCaptcha
 

softweri

Client
Joined
Mar 3, 2016
Messages
108
Reaction score
17
Points
18

Users Who Are Viewing This Thread (Total: 0, Members: 0, Guests: 0)