Что нового

Google ReCaptcha

mef-t

Осваивающий
Сообщения
306
Репутация
30
AutoIt: 3.3.14.12
Версия: 1.0

Категория: Интернет

Описание: Скрипт разгадывает Google ReCaptcha. Почти :-[. (я его на столько запробовал, что гугл меня периодически банит или выдает сложную капчу).
Суть в следующем. В капче выбирается аудио задание. Затем аудио-файл конвертируется в wav (или flac) и отправляется в тот же google для распознавания. Полученное значение вводим в капчу.

Код:
Код:
#include <IE.au3>
#include <HtmlXPath.au3>
#include <array.au3>
#include <WinHttp.au3>

Global $objAppIE, $iframe, $itag
Global $proxyUse = False
Global $sProxyServer = "IP:Port" ; указывается прокси формата ip:port

_IEErrorNotify(False)

$objAppIE = ObjCreate ( 'InternetExplorer.Application' )
$objAppIE.visible = True
$SinkObject = ObjEvent($objAppIE, "IEEvent_", "DWebBrowserEvents2")
$oMyError = ObjEvent("AutoIt.Error", "MyErrFunc") ; Инициализация обработчика ошибок COM

#region ;Randomization Related
$MIN_RAND        = 250
$MAX_RAND        = 1250
$LONG_MIN_RAND   = 4780
$LONG_MAX_RAND   = 11100
#endregion

$RECAPTCHA_PAGE_URL = "https://www.google.com/recaptcha/api2/demo"

$HOUNDIFY_CLIENT_KEY = "key" ;Ключ от cloud.google.com/speech/


Global $ArrayNumber[10][2] = [["zero", "0"], _
                ["one", "1"], _
                ["two", "2"], _
                ["three", "3"], _
                ["four", "4"], _
                ["five", "5"], _
                ["six", "6"], _
                ["seven", "7"], _
                ["eight", "8"], _
                ["nine", "9"]]
_ArrayAdd($ArrayNumber, 'hero|0')
_ArrayAdd($ArrayNumber, 'to|2')
_ArrayAdd($ArrayNumber, 'free|3')
_ArrayAdd($ArrayNumber, 'Kik|6')
_ArrayAdd($ArrayNumber, 'do|2')



solve()


Func solve()
	Local $challenge = True

	; Get a ReCaptcha Challenge
	$challenge = get_recaptcha_challenge()


	If $challenge = True Then

		; Get audio challenge
		get_audio_challenge()

		; Solve the audio challenge
		if not solve_audio_challenge() Then
			return False
		EndIf

		; Check if there is another audio challenge and solve it too
		while is_exists_by_xpath(_IEDocReadHTML($iframe), '//div[@class="rc-audiochallenge-error-message"]')
			ConsoleWrite("необходимо пройти еще квест" & @CRLF)
			$idiv = _IEGetObjById($iframe, "recaptcha-reload-button")
			$idiv.click()
			Sleep(Random($MIN_RAND, $MAX_RAND))

			; reload
			$idiv = _IEGetObjById($iframe, 'recaptcha-verify-button')
			While StringInStr($idiv.classname, 'rc-button-default-disabled') > 0
				Sleep(250)
				$idiv = _IEGetObjById($iframe, 'recaptcha-verify-button')
			WEnd

			solve_audio_challenge()
		WEnd

	EndIf

	; Switch to the ReCaptcha iframe to verify it is solved
	$iframe = _IEFrameGetCollection($objAppIE, 0)

	return is_exists_by_xpath(_IEDocReadHTML($iframe), '//span[@aria-checked="true"]')

EndFunc

Func get_recaptcha_challenge()
		; Navigate to a ReCaptcha page
		$objAppIE.navigate ($RECAPTCHA_PAGE_URL)
		While $objAppIE.ReadyState <> 4
			Sleep(250)
		WEnd
		Sleep(Random($MIN_RAND, $MAX_RAND))

		; Get all the iframes on the page
		$iframe = _IEFrameGetCollection($objAppIE, 0)
;~ 		Sleep(Random($MIN_RAND, $MAX_RAND))

		; Verify ReCaptcha checkbox is present
		if not is_exists_by_xpath(_IEDocReadHTML($iframe), '//div[@class="recaptcha-checkbox-checkmark" and @role="presentation"]') Then
			ConsoleWrite ("Не найден элемент во фрэйме - " & @LF)
;~ 			ContinueLoop
		EndIf

		; Click on ReCaptcha checkbox
		$idivs = _IETagNameGetCollection($iframe, 'div')
		For $idiv In $idivs
			If $idiv.classname = 'recaptcha-checkbox-checkmark' And $idiv.attributes.item('role').value="presentation" Then
				$idiv.click()
			EndIf
		Next
;~ 		Sleep(Random($LONG_MIN_RAND, $LONG_MAX_RAND))

		; Check if the ReCaptcha has no challenge
		If is_exists_by_xpath(_IEDocReadHTML($iframe), '//span[@aria-checked="true"]') Then
			ConsoleWrite("Рекапча без квеста!" & @LF)
			Return False
		else
			return True
		EndIf
EndFunc

Func get_audio_challenge()

	; Switch to the last iframe (the new one)
	$iframes = _IEFrameGetCollection($objAppIE)
	$iNumFrames = @extended

	While $iNumFrames < 2
		$iframes = _IEFrameGetCollection($objAppIE)
		$iNumFrames = @extended
;~ 		ConsoleWrite($iNumFrames & @LF)
	WEnd

	; Switch focus to ReCaptcha iframe
	$iframe = _IEFrameGetCollection($objAppIE, $iNumFrames-1)

	; Check if the audio challenge button is present
	$idiv = _IEGetObjById($iframe, "recaptcha-audio-button")
	While @error > 0
		Sleep(250)
		$idiv = _IEGetObjById($iframe, "recaptcha-audio-button")
	WEnd

	ConsoleWrite("Переход к аудиоквестам" & @LF)
	; Click on the audio challenge button
;~ 	$idiv = _IEGetObjById($iframe, "recaptcha-audio-button")
	$idiv.click()

	;waite load
	$idiv = _IEGetObjById($iframe, ":c")
	While @error > 0
		Sleep(250)
	WEnd

;~ 	Sleep(Random($LONG_MIN_RAND, $LONG_MAX_RAND))
EndFunc

Func solve_audio_challenge()
	; Verify audio challenge download button is present
	if not is_exists_by_xpath(_IEDocReadHTML($iframe), '//a[@class="rc-audiochallenge-download-link"]') and not is_exists_by_xpath(_IEDocReadHTML($iframe), '//div[@class="rc-text-challenge"]') Then
		ConsoleWrite("Не найдена ссылка для скачивания аудио" & @LF)
		return False
	EndIf

	; If text challenge - reload the challenge
	while is_exists_by_xpath(_IEDocReadHTML($iframe), '//div[@class="rc-text-challenge"]')
		ConsoleWrite("Получен текстовый квест. Перезагрузка" & @LF)
		$idiv = _IEGetObjById($iframe, 'recaptcha-reload-button')
		$idiv.click()
		Sleep(Random($MIN_RAND, $MAX_RAND))
	WEnd

	; Get the audio challenge URI from the download link

	$oLinks = _IELinkGetCollection($iframe)
	For $oLink In $oLinks
		If $oLink.classname = 'rc-audiochallenge-download-link' Then
			$download_link = $oLink.href
			ConsoleWrite("ссылка: " & $download_link & @crLF)
			ExitLoop
		EndIf
	Next

	$hTimer  = TimerInit()

	$idiv = _IEGetObjById($iframe, 'audio-response')
	$idiv.focus()
	$idiv.click()


	; Get the challenge audio to send to Google
	$audio_file = get_challenge_audio($download_link)

	; Send the audio to Google Speech Recognition API and get the output
	$audio_output = speech_to_text($audio_file)


;~ 	$iDiff = TimerDiff($hTimer)
;~ 	While $iDiff < 15000
;~ 		Sleep(250)
;~ 		$iDiff = TimerDiff($hTimer)
;~ 	WEnd

	; Enter the audio challenge solution
;~ 	$idiv = _IEGetObjById($iframe, 'audio-response')
;~ 	$idiv.focus()
	$idiv.value = $audio_output
	sleep(random($MIN_RAND, $MAX_RAND))

	; Click on verify
	$idiv = _IEGetObjById($iframe, 'recaptcha-verify-button')
	$idiv.click()
	sleep(random($MIN_RAND, $MAX_RAND))

	return True
EndFunc

Func get_challenge_audio($url)

	; Download the challenge audio and store in memory
	$ffmpeg = 'c:\Ivan\ffmpeg\bin\ffmpeg.exe'
	$Audioinput = @ScriptDir & '\audio.mp3'
	$AudioOutput = @ScriptDir & '\audio.wav'
	If FileExists($Audioinput) Then
		FileDelete($Audioinput)
	EndIf
	INetGet($url, $Audioinput, 1, 0)
	If FileExists($Audioinput) = 0 Then Sleep(1000)
	If FileExists($Audioinput) = 0 Then
		MsgBox(64, 'error', 'После загрузки mp3 файл не найден')
		Exit
	EndIf
	If FileExists($AudioOutput) Then
		FileDelete($AudioOutput)
	EndIf
;~ 		$runComand = $ffmpeg & ' -i ' & $Audioinput & ' -vn -ar 16000 -ac 1 -f wav ' & $AudioOutput
		$runComand = $ffmpeg & ' -i ' & $Audioinput & ' -f wav ' & $AudioOutput
	RunWait(@ComSpec & " /c " & $runComand, "", @SW_HIDE)
	While FileExists($AudioOutput) = 0
		Sleep(250)
	WEnd
	return $AudioOutput
EndFunc

Func speech_to_text($audio)

	Local $hOpen
	Local $Domen = 'speech.googleapis.com'


	#region ; connect
	If $proxyUse Then
		$hOpen = _WinHttpOpen('au3browser', $WINHTTP_ACCESS_TYPE_NAMED_PROXY, $sProxyServer) ;инициализируем использование WinHTTP-функций, указываем заголовок User-Agent
	Else
		$hOpen = _WinHttpOpen('au3browser') ;инициализируем использование WinHTTP-функций, указываем заголовок User-Agent
	EndIf
	If @error Then
		MsgBox(16, 'Ошибка', 'Не удалось инициализировать использование WinHttp-функций.')
		Exit 1
	EndIf
	$hConnect = _WinHttpConnect($hOpen, $Domen) ;создаём соеденение, указываем только домен/ip-адрес
	If @error Then
		MsgBox(16, 'Ошибка', 'Не удалось создать соеденение.')
		Exit 2
	EndIf
	#endregion

;~ 	$datasend = '{"config": { "encoding": "LINEAR16", "sampleRate": 16000, "languageCode": "en-US", "speech_context": {"phrases":["1","2","3","4","5","6","7","8","9","0"]}},"audio": {"content": "' & _BinaryFile($audio) & '"}}'
;~ 	$datasend = '{"config": { "encoding": "LINEAR16", "sampleRate": 11025, "languageCode": "en-US", "speech_context": {"phrases":["zero","one","two","three","four","five","six","seven","eight","nine"]}},"audio": {"content": "' & _BinaryFile($audio) & '"}}'
	$datasend = '{"config": { "encoding": "LINEAR16", "sampleRate": 11025, "languageCode": "en-US", "speech_context": {"phrases":["1","2","3","4","5","6","7","8","9","0","zero","one","two","three","four","five","six","seven","eight","nine"]}},"audio": {"content": "' & _BinaryFile($audio) & '"}}'
	$sDataReq = _WinHttpSimpleSSLRequest($hConnect, 'POST', '/v1beta1/speech:syncrecognize?key=' & $HOUNDIFY_CLIENT_KEY, Default, $datasend, 'Content-Type: application/json') ;авторизация

	$sDataReq = StringRegExp($sDataReq, 'transcript": ?"(.*?)"', 3)
	$result = ''
	For $i = 0 To UBound($sDataReq)-1
		$result &= $sDataReq[$i]
	Next
	$result = StringStripWS($result, 8)

	consoleWrite($result & @CRLF)
	For $i=0 To UBound($ArrayNumber)-1
		If StringInStr($result, $ArrayNumber[$i][0]) > 0 Then
			$result = StringReplace($result, $ArrayNumber[$i][0], $ArrayNumber[$i][1])
		EndIf
	Next

	ConsoleWrite($result & @CRLF)

	FileMove($audio, @ScriptDir & '\audio\' & $result & '.wav')
	ConsoleWrite(@error & @CRLF)

	_WinHttpCloseHandle($hConnect)
	_WinHttpCloseHandle($hOpen)

	Return $result

EndFunc

Func _BinaryFile($file)
	$fh=FileOpen($file, 16)
	$str=FileRead($fh)
	FileClose($fh)

	$str = _Base64Encode($str)
	$bData = StringReplace($str, @CR, '')
	$bData = StringReplace($str, @LF, '')
	Return $bData
EndFunc

Func _Base64Encode($sData)
    Local $oXml = ObjCreate("Msxml2.DOMDocument")
    If Not IsObj($oXml) Then
        SetError(1, 1, 0)
    EndIf

    Local $oElement = $oXml.createElement("b64")
    If Not IsObj($oElement) Then
        SetError(2, 2, 0)
    EndIf

    $oElement.dataType = "bin.base64"
    $oElement.nodeTypedValue = Binary($sData)
    Local $sReturn = $oElement.Text

    If StringLen($sReturn) = 0 Then
        SetError(3, 3, 0)
    EndIf

    Return $sReturn
EndFunc   ;==>_Base64Encode

Func is_exists_by_xpath($sHTML, $xpath)
	_HtmlXPath_Select($sHTML, $xpath)
	$iCount = @extended
	If $iCount > 0 Then return True
	return False
EndFunc


Примечание: Гугл достаточно плохо разгадывает капчу. Многие цифры пропускает. Изначально пробовал конвертировать в больший битрейт, но становится хуже. Полагаю, что следует наложить некоторые фильтры, но пока плохо в этом разбираюсь. Если кто поможет, буду благодарен.

Важно: Если подобного рода темы не следует публиковать на форуме, просьба сообщить, или самостоятельно удалить.
 

Angelionix

Новичок
Сообщения
4
Репутация
0
Проблема в том что при разгадывании нескольких recapcha , используя аудио файл, с одного ip, google или банит или да как и сказали выше выдает более сложную capcha или бывает такое что capcha просто становится бесконечной.
я пробовал на с# сделать, с использованием Microsoft Speech recognition , он разгадывалось так себе, сам движок распознования определял, что цифр 5, но отрабатывал только 2-3 и то не всегда правильно.
я вижу решение примерно такое -
1. Делается скриншот браузера
2. С помощью функций поиска картинки захватываются область с картинками, кнопка отправки, и область с заданием
3. область с картинки нарезается на 9 меньших, и перегоняются в переменные массивы
4. Далее исходя из того что найдено в область с заданием, мы проверяем картинки с базой соответсвующих изображений
5. При совпадении записываются координаты соответсвующей картинки в массив ансер
6. Прокликиваеются точки уже в окне браузера по координатам из ансера, и нажимается кнопка отправить
7. В зависимости от того какая кнопка - Отправить или Некст, уже дальше выполняем программу
 

Angelionix

Новичок
Сообщения
4
Репутация
0
ну антигейт эт хорошо если у тебе надо решать капчу относительно нечасто, или если выхлоп с действия будет покрывать стоимость решения капчи на антигейте. в иных случаях если капча не очень сложная и ее надо будет решать тычячи раз. то есть смысл заморочиться и сделать свою локальную капча-решалку. Либо как я выше писал, или же используя нейронные сети. Так же как вариант это привязать CapMonster от zennolab. Ведь он прослушивает порты на локальном серваке, через которые отправлятся капчи на сервисы решения. И да тогда можно будет заюзать antigate.api , только решать их будет уже не сервис в сети, а Capmonster.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Правильно, но тут же рекапча и она ни разу не простенькая что бы сделать свою решалку.
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
SuperSonic

Предупреждение За нарушение общих правил (пункт В.2):
Старайтесь избегать “Over quoting” (преувеличенное цитирование) - цитируйте только необходимую часть сообщения, которая наилучшим образом подчеркнёт суть цитируемого.


С уважением, ваш Глобальный модератор.





Будьте так добры, удалите рекламу о сотрудничестве из подписи.
Для этого есть раздел Партнерство
 
Автор
mef-t

mef-t

Осваивающий
Сообщения
306
Репутация
30
Angelionix сказал(а):
бывает такое что capcha просто становится бесконечной.
Это заблуждение.
Или гугл требует ввести 2 правильных капчи подряд или же считает предыдущие ответ не верным.
Вполне возможно, что действителен только второй вариант.
Бесконечной капчи нет.


Добавлено:
Сообщение автоматически объединено:

Антигейт слишком много кушает.
Да и время.
Я пробовал сначала его прикрутить: от 10 секунд до 1,5 минуты ожидания на 1 капчу. Через 3 капчи ошибка в распознавании.
Потому и стал строить другой вариант.
Осталось только распознавать правильно значения.
Я могу понять некоторые цифры, которые не получается распознать. Но есть цифры, которые четко произносятся, но не распознаются.
Полагаю, тут нужно еще сам файл корректировать, переводя все произношения в одну тональность. А это нужна помощь специалистов по звуку.

А вообще, это все не для дела какого-то, а любопытства ради.
Хочется поиграться с корпорацией, строящей такую защиту от машины.
 
Верх