Инструменты пользователя

Инструменты сайта


Боковая панель

Перевод этой страницы:

ru:addons:capmonster:rc-audio

Это старая версия документа.


ReCaptcha Audio

В программе CapMonster 2, начиная с версии 2.5.0.0 появилась возможность распознавать звуковую рекапчу старого и нового типа. В программе будет доступен модуль ZennoLab.AudioReCaptcha. Работает это так: когда на странице встречается ReCaptcha, нужно выбрать распознавание через аудиозапись и отправить ее в CapMonster.

Принцип работы:


Использование в ZennoPoster

Для отправки звуковых каптч из ZennoPoster версии 5.9.5.1+ вы можете использовать подготовленный нами сниппет. Код сниппета доступен ниже.

// Основные параметры
 
// время ожидания
var waitTime = 2000;
// количество попыток распознать
var tryRecognize = 3;
// количество попыток загрузить элемент
var tryLoadElement = 60;
// показывать сообщения о прогрессе распознавания
var needShowMessages = false;
// проверять корректность распознанного ответа
var needToCheck = true;
 
// Вспомогательные переменные
 
// вкладка
var tab = instance.ActiveTab;
// поздравляем, вы не робот
var success = false;
// аудио файл
var file = string.Empty;
// файл был удален
var fileDeleted = true;
// ответ на аудио каптчу
var answer = string.Empty;
// новый вид рекаптчи 2
var isNewView = true;
// рекаптча 1
var isRecaptcha1 = false;
// время вышло 
var timeout = false;
// ошибка загрузки файла
var fileLoadingError = false;
// cписок урлов скаченных файлов
var usedURLs = new List<string>();  
 
// поиск кнопки открытия формы с аудио заданием
Action TryOpenAudioForm = () => {
	for (int k = 0; k < tryLoadElement; k++)
	{
		var audioButton = tab.FindElementByAttribute("div", "id", "recaptcha-audio-button", "regexp", 0);
		// если нашли
		if (!audioButton.IsVoid)
		{
			// клик по кнопке
			audioButton.Click();
			break;
		}
		System.Threading.Thread.Sleep(waitTime); // подождём немного
		if (k == (tryLoadElement - 1)) timeout = true;
	}
	System.Threading.Thread.Sleep(waitTime); // подождём немного
};
 
// открытие аудиозадания
Action OpenAudioTask= () => {
	project.SendInfoToLog("Открываем форму с аудио заданием", needShowMessages);
	if (isNewView)
	{
		//проверяем тип задания формы
		var task = tab.FindElementByAttribute("div", "class", "rc-imageselect-desc-wrapper", "regexp", 0);
		if (!task.IsVoid) TryOpenAudioForm(); // найдено графическое задание, значит открываем аудио
	}
	else
	{
		var elem = tab.FindElementByAttribute("input:submit", "class", @"fbc-button-audio fbc-button", "regexp", 0);
		if (!elem.IsVoid) elem.Click();
 
		tab.WaitDownloading();
		var errorElem = tab.FindElementByAttribute("div", "class", "fbc-message", "regexp", 0);
		if (!errorElem.IsVoid)
		{
			var attr = errorElem.GetAttribute("innertext");
			if (attr.Contains("Please enable JavaScript and/or update your browser to get an audio challenge"))
			{
				throw new Exception("Не получилось открыть вкладку с аудиозаданием, попробуйте изменить userAgent");
			}
		}
	}
};
 
// Определение версии рекапчи
Action NotRobotClick= () => {
	for (int k = 0; k < tryLoadElement; k++)
	{
		// поиск кнопки "Я не робот"
		var notRobot = tab.FindElementByAttribute("div", "class", "recaptcha-checkbox-checkmark", "regexp", 0);
		// если нашли
		if (!notRobot.IsVoid)
		{
			// клик по кнопке
			notRobot.Click();
			// подождём немного
			System.Threading.Thread.Sleep(waitTime);
 
			// если ввод каптчи не требуется
			var check = tab.FindElementByAttribute("div", "class", "recaptcha-checkbox-checkmark", "regexp", 0);
			if (!check.IsVoid)
			{
				if (check.OuterHtml.Contains("style=\"\""))
				{
					success = true;
					break;
				}
			}
 
			// Ждем пока загрузится форма
			for (int j = 0; j < tryLoadElement; j++)
			{
				var loadedForm = tab.FindElementByAttribute("div", "class", "primary-controls", "regexp", 0);
				if (!loadedForm.IsVoid) break;
				else System.Threading.Thread.Sleep(waitTime); // подождём загрузки элемента
				if (j == (tryLoadElement - 1)) timeout = true;
			}
			break;
		}
		else
		{
			// проверяем наличие аудио кнопки рекаптчи 1
			HtmlElement r1 = tab.FindElementById("recaptcha_switch_audio");
			if (!r1.IsVoid)
			{
				r1.Click();
				isRecaptcha1 = true;
				break;
			}
 
			// проверяем вид рекаптчи2
			var elem = tab.FindElementByAttribute("input:submit", "class", @"fbc-button-audio fbc-button", "regexp", 0);
			if (!elem.IsVoid)
			{
				isNewView = false;
				break;
			}
			System.Threading.Thread.Sleep(waitTime); // подождём загрузки элемента
		}
		if (k == (tryLoadElement - 1)) timeout = true;
	}
};
 
// скачиваем mp3-файл
Action GetAudioFile= () => {
 
	var href = String.Empty;
 
	// получаем аудио задание
	for (int k = 0; k < tryLoadElement; k++)
	{
		if (isRecaptcha1)
		{
			var audioChallenge = tab.FindElementByAttribute("a", "id", "recaptcha_audio_download", "text", 0);
			// если нашли, получаем ссылку на аудио файл
			if (!audioChallenge.IsVoid)
			{
				href = audioChallenge.GetAttribute("href");
				break;
			}
			else System.Threading.Thread.Sleep(waitTime);
		}
		else
		{
			if (isNewView)
			{
				var audioChallenge = tab.FindElementByAttribute("a", "class", "rc-audiochallenge-download-link", "regexp", 0);
				// если нашли, получаем ссылку на аудио файл
				if (!audioChallenge.IsVoid)
				{
					href = audioChallenge.GetAttribute("href");
					break;
				}
				else
				{
					var reload = tab.FindElementByAttribute("div", "id", "recaptcha-reload-button", "regexp", 0);
					if (!reload.IsVoid)
						reload.Click();
				}
				System.Threading.Thread.Sleep(waitTime); // подождём загрузки элемента
			}
			else
			{
				var audioChallenge = tab.FindElementByAttribute("audio", "class", "fbc-audio-controls", "regexp", 0);
				// если нашли, получаем ссылку на аудио файл
				if (!audioChallenge.IsVoid)
				{
					href = audioChallenge.FindChildByAttribute("source", "src", ".mp3", "text", 0).GetAttribute("src");
					href = "https://www.google.com" + href;
					break;
				}
				else System.Threading.Thread.Sleep(waitTime); // подождём загрузки элемента
			}
		}
		if (k == (tryLoadElement - 1)) timeout = true;
	}
 
	foreach (var usedUrl in usedURLs)
	{
		if (usedUrl.Contains(href))
			throw new Exception("Отсутствует новый аудио файл");
	}
	usedURLs.Add(href);
 
	project.SendInfoToLog("Скачиваем аудио файл", needShowMessages);
	try
	{
		var proxy = instance.GetProxy();
		var respType = ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.File;
		var timeoutRequest = 30000;
		var cookies = instance.GetCookie("google.com", true);
		var userAgent = project.Profile.UserAgent;
		var maxRedirectCount = 1;
		var downloadPath = project.Directory + "\\audiofiles";
		file = ZennoPoster.HttpGet(href, proxy, "UTF8", respType, timeoutRequest, cookies, userAgent, false, maxRedirectCount, null, downloadPath);
		fileDeleted = false;
	}
	catch (Exception ex)
	{
		throw new Exception("Не удалось скачать аудио файл");
	}
};
 
Action Recognize= () => {
	project.SendInfoToLog("Распознаем", needShowMessages);
	try 
	{
		if (!File.Exists(file)) 
		{
			fileLoadingError = true;
			fileDeleted = true;
			return;
		}
		var bytes = File.ReadAllBytes(file);
		if (bytes.Length < 1024)
		{
			fileLoadingError = true;
			return;
		}
		string str = Convert.ToBase64String(bytes);
		var rc = ZennoPoster.CaptchaRecognition("CapMonster2.dll", str, "CapMonsterModule=ZennoLab.AudioReCaptcha&ParallelMode=true");
		answer = rc.Split(new [] {"-|-"}, StringSplitOptions.RemoveEmptyEntries)[0];
                if (answer.Contains("133193320491090004119440")) throw new Exception("Your IP was banned!");
	} 
	finally 
	{
        if (File.Exists(file)) 
	    {
			File.Delete(file);
			fileDeleted = true;
        }
	}
};
 
Action InputAnswer= () => {
	if (!String.IsNullOrEmpty(answer) && answer != "sorry")
	{
		project.SendInfoToLog("Вводим ответ", needShowMessages);
		HtmlElement audioAnswerInput = null;
		// ищем поле для ввода ответа
		if (isRecaptcha1)
		{
			audioAnswerInput = tab.FindElementByAttribute("input:text", "id", "recaptcha_response_field", "text", 0);
		}
		else
		{
			if (isNewView) audioAnswerInput = tab.FindElementByAttribute("input:text", "id", "audio-response", "regexp", 0);
			else audioAnswerInput = tab.FindElementByAttribute("input:text", "id", "response", "text", 0);
		}
 
		// если нашли
		if (!audioAnswerInput.IsVoid)
		{
			// вводим ответ
			audioAnswerInput.SetValue(answer, "None", false);
		}
 
		// подождём немного
		System.Threading.Thread.Sleep(waitTime);
	}
	else throw new Exception("Ответ не получен");
};
 
// Подтверждаем
Action SubmitAnswer= () => {
	// ищем кнопку "Подтвердить"
	HtmlElement apply = null;
	if (isNewView) apply = tab.FindElementById("recaptcha-verify-button");
	else apply = tab.FindElementByAttribute("div", "class", "fbc-button-verify", "regexp", 0).FindChildByAttribute("input:submit", "fulltag", "input:submit", "text", 0);
 
	if (!apply.IsVoid) apply.Click();
 
	// подождём немного
	System.Threading.Thread.Sleep(waitTime);
};
 
// Проверяем правильность для старого вида рекапчи 2
Action CheckOldView= () => {
	// Проверяем, была ли ошибка в распознавании
	project.SendInfoToLog("Проверяем правильность", needShowMessages);
	HtmlElement he = tab.FindElementByAttribute("div", "class", "fbc-error", "regexp", 0);
	if (!he.IsVoid) 
	{
		return;
	}
 
	string txt = string.Empty;
	// ищем текст, который надо вставить
	for (int k = 0; k < tryLoadElement; k++)
	{
		HtmlElement heGetText = tab.FindElementByAttribute("textarea", "dir", "ltr", "regexp", 0);
		if (!heGetText.IsVoid)
		{
			txt = heGetText.GetAttribute("value");
			break;	
		}
		else 
		{
			System.Threading.Thread.Sleep(waitTime); // подождём немного
			continue;
		}
		if (k == (tryLoadElement - 1)) timeout = true;
	}
 
	// ищем куда вставлять текст
	for (int k = 0; k < tryLoadElement; k++)
	{
		HtmlElement hePutText = tab.FindElementByAttribute("textarea", "id", "g-recaptcha-response", "regexp", 0);
		if (!hePutText.IsVoid)
		{
			hePutText.SetValue(txt, "None", false);
			break;	
		}
		else 
		{
			System.Threading.Thread.Sleep(waitTime); // подождём немного
			continue;
		}
		if (k == (tryLoadElement - 1)) timeout = true;
	}
 
	// нажимаем "Подтвердить"
	for (int k = 0; k < tryLoadElement; k++)
	{
		var submit = tab.FindElementByAttribute("input:submit", "fulltag", "input:submit", "regexp", 0);
		if (!submit.IsVoid)
		{
			submit.Click();
			break;
		}
		else 
		{
			System.Threading.Thread.Sleep(waitTime); // подождём немного
			continue;
		}
		if (k == (tryLoadElement - 1)) timeout = true;
	}
	success = true;
};
 
// проверим правильность ответа рекапчи 2
Action Check= () => {
 	project.SendInfoToLog("Проверяем правильность", needShowMessages);
	for (int k = 0; k < tryLoadElement; k++)
	{
		var checkAnswer = tab.FindElementByAttribute("div", "class", "recaptcha-checkbox-checkmark", "regexp", 0);
		if (!checkAnswer.IsVoid)
		{
			if (checkAnswer.OuterHtml.Contains("style=\"\""))
				success = true;
			else
				success = false;
			return;
		}
		if (k == (tryLoadElement - 1)) timeout = true;
		System.Threading.Thread.Sleep(waitTime);
	}
};
 
// Кликаем по кнопке я не робот, если она есть
NotRobotClick();
if (success) return "ok";
 
// Пытаемся распознать рекапчу
for (int i = 0; i < tryRecognize; i++)
{
	if (!isRecaptcha1) OpenAudioTask();
	if (timeout) break;
	GetAudioFile();
	if (timeout) break;
	Recognize();
	if (fileLoadingError) 
	{
		fileLoadingError = false;
		continue;
	}
	if (timeout) break;
	InputAnswer();
	if (timeout) break;
	if (!fileDeleted)
	{
		if (File.Exists(file))
		{
			File.Delete(file);
			fileDeleted = true;
		}
	}
 
	if (isRecaptcha1) return "ok";
	SubmitAnswer();
 
	if (!needToCheck) return "ok";
 
	if (timeout) break;
	if (!isNewView) CheckOldView();
	else Check();
	if (success) return "ok";
}
 
if (timeout) throw new Exception("Вышло время ожидания загрузки элемента");
else throw new Exception("Не распознано. Закончились попытки распознать, прежде чем ответ был засчитан");

Примечание

Сниппет работает и в случае, когда в браузере используется старый или телефонный UserAgent.
В обязательном порядке необходимо использовать прокси, поскольку после 3-5 распознанных каптч с одного IP рекаптча запрещает доступ к аудиофайлу.
Если каптча не распознается с первого раза сниппет выполнит вторую попытку. Количество попыток загрузить элементы, время ожидания, количество попыток распознать капчу и необходимость проверки корректности ответа можно менять с помощью переменных:

// время ожидания
var waitTime = 1000;
// количество попыток распознать
var tryRecognize = 2;
// количество попыток загрузить элемент
var tryLoadElement = 60;
// проверять корректность распознанного ответа
var needToCheck = true;
// показывать сообщения о прогрессе распознавания
var needShowMessages = false;


Функция отправки каптчи на сервис выглядит следующим образом:

ZennoPoster.CaptchaRecognition("CapMonster2.dll", str, "CapMonsterModule=ZennoLab.AudioReCaptcha&ParallelMode=true");

, где через знак «&» перечислены параметры сервиса CapMonster2.dll: указание имени модуля и настройка распознавания в параллельном режиме, соответственно.

ru/addons/capmonster/rc-audio.1462975529.txt.gz · Последние изменения: 2016/05/11 14:05 — afameless