Что нового

[Сеть, интернет] Ошибка в работе скрипта при инициализации IE

A

at

Гость
Версия AutoIt: 3.3.12
Версия IE: 11.0.17

Час добрый, Всем! Есть программа, которая вводит подготовленные данные в форму оплаты на сайте билайн. Вводим номер телефона и сумму в окно программы и нажимаем кнопку. Программа сама выберет платежные данные из нашего списка и автоматически пополнит счет нашего телефона. В общем для кого-то может оказаться полезной.
Код:
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

#include <IE.au3>
#include <File.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>

Opt('GUIOnEventMode', 1)

_GDIPlus_Startup()

Global $oIE = _IECreate('about:blank', 0, 1, 0, 0)

$Form = GUICreate("Beeline autpay by BIOS", 305, 84, 192, 114)
GUISetIcon(@ScriptFullPath)
$ButtonAction = GUICtrlCreateButton("Пополнить счет", 8, 40, 283, 33)
$InputPhonePrefix = GUICtrlCreateInput("", 64, 8, 42, 21, $ES_NUMBER)
GUICtrlSetLimit(-1, 3, 3)
$InputPhoneNumber = GUICtrlCreateInput("", 108, 8, 96, 21, $ES_NUMBER)
GUICtrlSetLimit(-1, 7, 7)
$InputPhoneAmount = GUICtrlCreateInput("", 248, 8, 41, 21, $ES_NUMBER)
GUICtrlSetLimit(-1, 3, 1)
$Label1 = GUICtrlCreateLabel("Телефон:", 8, 8, 49, 17)
$Label2 = GUICtrlCreateLabel("Сумма:", 208, 8, 41, 17)
GUISetState(@SW_SHOW)

GUICtrlSetOnEvent($ButtonAction, 'Action')

GUISetOnEvent($GUI_EVENT_CLOSE, '_ExitH')

OnAutoItExitRegister('_Exit')

While Sleep(20)

WEnd

Func Action()
	_IENavigate($oIE, 'https://oplata.beeline.ru/mobile/', 0)
	Sleep(500)
	_IELoadWait($oIE, 100, 20000)

	$sData = FileRead(@ScriptDir & '\paydata.txt')
	$sData = StringReplace($sData, @CR, '')
	$sData = StringStripWS($sData, 3)
	$aData = StringSplit($sData, @LF)
	For $iData = 1 To $aData[0]
		;номер карты ; месяц на карте ; год на карте ; имя владельца на карте; CVC2-код
		$aPayment = StringSplit($aData[$iData], ';')
		If $aPayment[0] > 5 Then ContinueLoop

		$oForm = _IEGetObjById($oIE, 'payment-form')
		$oInputPrefix = _IEFormElementGetObjByName($oForm, 'Payments[0].CtnPrefix')
		_IEFormElementSetValue($oInputPrefix, GUICtrlRead($InputPhonePrefix))
		$oInputNumber = _IEFormElementGetObjByName($oForm, 'Payments[0].Ctn')
		_IEFormElementSetValue($oInputNumber, GUICtrlRead($InputPhoneNumber))
		$oInputAmount = _IEFormElementGetObjByName($oForm, 'Payments[0].Sum')
		_IEFormElementSetValue($oInputAmount, GUICtrlRead($InputPhoneAmount))
		Sleep(500)
		$oInputCardNumber = _IEGetObjById($oIE, 'CardNumber')
		_IEFormElementSetValue($oInputCardNumber, $aPayment[1])
		$oInputCardMonth = _IEGetObjById($oIE, 'CardMonth')
		_IEFormElementSetValue($oInputCardMonth, $aPayment[2])
		$oInputCardYear = _IEGetObjById($oIE, 'CardYear')
		_IEFormElementSetValue($oInputCardYear, $aPayment[3])
		$oInputCardHolder = _IEGetObjById($oIE, 'CardHolder')
		_IEFormElementSetValue($oInputCardHolder, $aPayment[4])
		$oInputCardCode = _IEGetObjById($oIE, 'CardCode')
		_IEFormElementSetValue($oInputCardCode, $aPayment[5])
		Sleep(500)
		$oCaptchaImg = _IEGetObjById($oIE, 'captcha-image')
		$sCaptcha = _Captcha_RecognizeByElement($oIE, $oCaptchaImg, 1, 5, 5)
		$oCaptcha = _IEGetObjById($oIE, 'Captcha')
		_IEFormElementSetValue($oCaptcha, $sCaptcha)

		_IEFormElementCheckBoxSelect($oForm, 'true', 'AgreeTerms')
		Sleep(500)
		_IEFormSubmit($oForm, 0)
		Sleep(1000)
		_IELoadWait($oIE, 100, 20000)

		$aData[$iData] &= ';' & @MDAY & '.' & @MON & '.' & @YEAR

		ExitLoop
	Next

	FileDelete(@ScriptDir & '\paydata.txt')
	For $iData = 1 To $aData[0]
		FileWriteLine(@ScriptDir & '\paydata.txt', $aData[$iData])
	Next

EndFunc   ;==>Action

Func _Captcha_RecognizeByElement($oIE, $oEl, $iNumeric = 0, $iMin = 1, $iMax = 20, $xSmesh = 0, $ySmesh = 0)
	$oEl.parentNode.removeChild($oEl)
	$oIE.document.body.appendChild($oEl)
	$oEl.style.position = "absolute"
	$oEl.style.top = "200px"
	$oEl.style.left = "100px"
	$oEl.style.background = "#ffffff"
	$oEl.style.opacity = "0.99"
	Sleep(100)

	$oIE.document.parentWindow.scrollTo(0, 0)

	Local $hWin = _IEPropertyGet($oIE, 'hwnd')
	$aPos = WinGetPos($hWin)
	Dim $aTarget[4] = [$aPos[0], $aPos[1], $aPos[2], $aPos[3]]
	If $aTarget[0] > @DesktopWidth - 500 Then $aTarget[0] = @DesktopWidth - 500
	If $aTarget[1] > @DesktopHeight - 500 Then $aTarget[1] = @DesktopHeight - 500
	If $aTarget[2] < 500 Then $aTarget[2] = 500
	If $aTarget[3] < 500 Then $aTarget[3] = 500
	WinMove($hWin, '', $aTarget[0], $aTarget[1], $aTarget[2], $aTarget[3])
	WinActivate($hWin)
	Local $sImg = _TempFile(@TempDir, '~', '.jpg')
	_ScreenCapture_CaptureWnd($sImg, $hWin, 0, 0, -1, -1, False)

	Local $aClassList = WinGetClassList($hWin)
	$aClassList = StringSplit($aClassList, @LF)
	Local $aMax = 0
	Local $iSMax = 0
	Local $aPos
	Local $i = 1
	While 1
		$aPos = ControlGetPos($hWin, '', '[CLASS:Internet Explorer_Server;INSTANCE:' & $i & ']')
		If @error Then ExitLoop

		If $aPos[2] * $aPos[3] > $iSMax Then
			$iSMax = $aPos[2] * $aPos[3]
			$aMax = $aPos
		EndIf
		$i += 1
	WEnd

	$aPos = WinGetClientSize($hWin)
	Local $aPos2 = WinGetPos($hWin)

	Local $hBit = _GDIPlus_BitmapCreateFromFile($sImg)
	Local $hBit2 = _GDIPlus_BitmapCloneArea($hBit, 90 + $aMax[0] + (($aPos2[2] - $aPos[0]) / 2) + $xSmesh, 190 + $aMax[1] + (($aPos2[3] - $aPos[1]) / 2) + 10 + $ySmesh, $oEl.width + 20, $oEl.height + 20)

	_GDIPlus_BitmapDispose($hBit)
	Local $sImg2 = _TempFile(@TempDir, '~', '.jpg')
	_GDIPlus_ImageSaveToFile($hBit2, $sImg2)

	_GDIPlus_BitmapDispose($hBit2)

	Return _Captcha_ResolveFile($sImg2, IniRead(@ScriptDir & '\Settings.ini', 'AntiCaptcha', 'Key', ''), 0, 0, $iNumeric, 0, $iMin, $iMax)
EndFunc   ;==>_Captcha_RecognizeByElement

Func _Captcha_ResolveFile($file_name, $captcha_key, $is_phrase = 0, $is_regsense = 0, $is_numeric = 0, $is_calc = 0, $min_len = 0, $max_len = 0, $is_russian = 0, $max_bid = 0, $bStore = False)
	$ag = ObjCreate('AG_Tools.cl_CaptchaRec')
	If @error Then
		RunWait('regsvr32.exe /S "' & @ScriptDir & '\AG_Tools.dll"')
		$ag = ObjCreate('AG_Tools.cl_CaptchaRec')
		If @error Then Return 'ERR Register'
	EndIf
	$id = 0
	$text = 0
	$ret = 0
	$return = $ag.AG_RecognizeFile($captcha_key, $file_name, 0, '', 0, $id, $text, $ret, $is_phrase, $is_regsense, $is_numeric, $is_calc, $min_len, $max_len, $is_russian, $max_bid)
	If $bStore <> True Then FileDelete($file_name)
	If StringLeft($return, 3) = 'OK|' Then Return StringTrimLeft($return, 3)
	Return $text
EndFunc   ;==>_Captcha_ResolveFile

Func _ExitH()
	Exit
EndFunc   ;==>_ExitH

Func _Exit()
	_GDIPlus_Shutdown()
	If IsObj($oIE) Then _IEQuit($oIE)
EndFunc   ;==>_Exit

Описание: Недавно стал наблюдать вот такую ошибку. Появляется не сразу при запуске программы, а примерно через 10-15 секунд после того, как отправлен запрос в IE на oplata.beeline.ru. Есть мнение, что проблема в инициализации IE. Но предполагаю, что есть способы обходить глюки эксплоера, если вопрос только в этом. Прошу помочь разобраться в чем ошибка или, по возможности, показать рабочее решение.

P.S. Скрипт сначала работал практически без глюков. Только иногда инициализация IE при первом запуске происходила не корректно, что приводило к аварийному завершению работы скрипта. Ошибка стала появляться более стабильно через некоторое время. Чистка IE и реестра первое время снимала проблему, но теперь скрипт окончательно отказывается работать.

За ранее всем спасибо!

Примечания: В архиве библиотека антикапча, файл настроек, файл с данными для ввода в форму. Кто возьмется помочь ключ от антикапчи скину в личку
 

Вложения

  • err_beeline.jpg
    err_beeline.jpg
    9.3 КБ · Просмотры: 10
  • beelinePayer.rar
    25.7 КБ · Просмотры: 1

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,320
at,
В Вашем коде нет ни одной проверки на возврат ошибок из функций, такой подход, ИМХО, в корне неправильный.
 
Автор
A

at

Гость
Прошу подсказать где ошибка при таком варианте
Код:
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

#include <IE.au3>
#include <File.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>

Opt('GUIOnEventMode', 1)
Opt('TrayIconDebug', 1)

_GDIPlus_Startup()

Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

Global $oIE = _IECreate('about:blank', 0, 1, 0, 0)

$Form = GUICreate("Beeline autopay by BIOS", 305, 84, 192, 114)
GUISetIcon(@ScriptFullPath)
$ButtonAction = GUICtrlCreateButton("Пополнить счет", 8, 40, 283, 33)
$InputPhonePrefix = GUICtrlCreateInput("", 64, 8, 42, 21, $ES_NUMBER)
GUICtrlSetLimit(-1, 3, 3)
$InputPhoneNumber = GUICtrlCreateInput("", 108, 8, 96, 21, $ES_NUMBER)
GUICtrlSetLimit(-1, 7, 7)
$InputPhoneAmount = GUICtrlCreateInput("", 248, 8, 41, 21, $ES_NUMBER)
GUICtrlSetLimit(-1, 3, 1)
$Label1 = GUICtrlCreateLabel("Телефон:", 8, 8, 49, 17)
$Label2 = GUICtrlCreateLabel("Сумма:", 208, 8, 41, 17)
GUISetState(@SW_SHOW)

GUICtrlSetOnEvent($ButtonAction, 'Action')

GUISetOnEvent($GUI_EVENT_CLOSE, '_ExitH')

OnAutoItExitRegister('_Exit')

While Sleep(20)

WEnd

Func Action()
	_IENavigate($oIE, 'https://oplata.beeline.ru/mobile', 0)
	Sleep(500)
	_IELoadWait($oIE, 100, 20000)

	$sData = FileRead(@ScriptDir & '\paydata.txt')
	$sData = StringReplace($sData, @CR, '')
	$sData = StringStripWS($sData, 3)
	$aData = StringSplit($sData, @LF)
	For $iData = 1 To $aData[0]
		;номер карты ; месяц на карте ; год на карте ; имя владельца на карте; CVC2-код
		$aPayment = StringSplit($aData[$iData], ';')
		If $aPayment[0] > 5 Then ContinueLoop

		$oForm = _IEGetObjById($oIE, 'payment-form')
		$oInputPrefix = _IEFormElementGetObjByName($oForm, 'Payments[0].CtnPrefix')
		_IEFormElementSetValue($oInputPrefix, GUICtrlRead($InputPhonePrefix))
		$oInputNumber = _IEFormElementGetObjByName($oForm, 'Payments[0].Ctn')
		_IEFormElementSetValue($oInputNumber, GUICtrlRead($InputPhoneNumber))
		$oInputAmount = _IEFormElementGetObjByName($oForm, 'Payments[0].Sum')
		_IEFormElementSetValue($oInputAmount, GUICtrlRead($InputPhoneAmount))
		Sleep(500)
		$oInputCardNumber = _IEGetObjById($oIE, 'CardNumber')
		_IEFormElementSetValue($oInputCardNumber, $aPayment[1])
		$oInputCardMonth = _IEGetObjById($oIE, 'CardMonth')
		_IEFormElementSetValue($oInputCardMonth, $aPayment[2])
		$oInputCardYear = _IEGetObjById($oIE, 'CardYear')
		_IEFormElementSetValue($oInputCardYear, $aPayment[3])
		$oInputCardHolder = _IEGetObjById($oIE, 'CardHolder')
		_IEFormElementSetValue($oInputCardHolder, $aPayment[4])
		$oInputCardCode = _IEGetObjById($oIE, 'CardCode')
		_IEFormElementSetValue($oInputCardCode, $aPayment[5])
		Sleep(500)

		$sOldUrl = _IEPropertyGet($oIE, 'locationurl')
		Do
			$oForm = _IEGetObjById($oIE, 'payment-form')

			Do
				$oCaptchaRefresh = _IEGetObjById($oIE, 'refresh-captcha')
				_IEAction($oCaptchaRefresh, 'click')
				Sleep(2000)
				$oCaptchaImg = _IEGetObjById($oIE, 'captcha-image')
				$sCaptcha = _Captcha_RecognizeByElement($oIE, $oCaptchaImg, 1, 5, 5)
			Until Not StringInStr($sCaptcha, 'ERROR')

			$oCaptcha = _IEGetObjById($oIE, 'Captcha')
			_IEFormElementSetValue($oCaptcha, $sCaptcha)

			_IEFormElementCheckBoxSelect($oForm, 'true', 'AgreeTerms')
			Sleep(500)
			_IEFormSubmit($oForm, 0)
			Sleep(1000)
			_IELoadWait($oIE, 100, 20000)
		Until _IEPropertyGet($oIE, 'locationurl') <> $sOldUrl

		$aData[$iData] &= ';' & @MDAY & '.' & @MON & '.' & @YEAR

		$oStatusDiv = False
		Do
			$oDivs = _IETagNameGetCollection($oIE, 'div')
			For $oDiv In $oDivs
				If StringInStr($oDiv.className, 'status ') Then
					$oStatusDiv = $oDiv
					ExitLoop
				EndIf
			Next
		Until IsObj($oStatusDiv)
		Sleep(2000)
		While 1
			If StringInStr($oStatusDiv.className, 'status_error') Then
				$aData[$iData] &= ';' & _IEPropertyGet($oStatusDiv, 'innertext')
				ExitLoop
			EndIf

			If Not (StringInStr($oStatusDiv.className, 'status_loading') and StringInStr($oStatusDiv.className, 'status_error')) Then ExitLoop
		WEnd
	Next

	FileDelete(@ScriptDir & '\paydata.txt')
	For $iData = 1 To $aData[0]
		FileWriteLine(@ScriptDir & '\paydata.txt', $aData[$iData])
	Next

EndFunc   ;==>Action

Func _Captcha_RecognizeByElement($oIE, $oEl, $iNumeric = 0, $iMin = 1, $iMax = 20, $xSmesh = 0, $ySmesh = 0)
	$oEl.parentNode.removeChild($oEl)
	$oIE.document.body.appendChild($oEl)
	$oEl.style.position = "absolute"
	$oEl.style.top = "200px"
	$oEl.style.left = "100px"
	$oEl.style.background = "#ffffff"
	;$oEl.style.opacity = "0.99"
	Sleep(100)

	$oIE.document.parentWindow.scrollTo(0, 0)

	Local $hWin = _IEPropertyGet($oIE, 'hwnd')
	$aPos = WinGetPos($hWin)
	Dim $aTarget[4] = [$aPos[0], $aPos[1], $aPos[2], $aPos[3]]
	If $aTarget[0] > @DesktopWidth - 500 Then $aTarget[0] = @DesktopWidth - 500
	If $aTarget[1] > @DesktopHeight - 500 Then $aTarget[1] = @DesktopHeight - 500
	If $aTarget[2] < 500 Then $aTarget[2] = 500
	If $aTarget[3] < 500 Then $aTarget[3] = 500
	WinMove($hWin, '', $aTarget[0], $aTarget[1], $aTarget[2], $aTarget[3])
	WinActivate($hWin)
	Local $sImg = _TempFile(@TempDir, '~', '.jpg')
	_ScreenCapture_CaptureWnd($sImg, $hWin, 0, 0, -1, -1, False)

	Local $aClassList = WinGetClassList($hWin)
	$aClassList = StringSplit($aClassList, @LF)
	Local $aMax = 0
	Local $iSMax = 0
	Local $aPos
	Local $i = 1
	While 1
		$aPos = ControlGetPos($hWin, '', '[CLASS:Internet Explorer_Server;INSTANCE:' & $i & ']')
		If @error Then ExitLoop

		If $aPos[2] * $aPos[3] > $iSMax Then
			$iSMax = $aPos[2] * $aPos[3]
			$aMax = $aPos
		EndIf
		$i += 1
	WEnd

	$aPos = WinGetClientSize($hWin)
	Local $aPos2 = WinGetPos($hWin)

	Local $hBit = _GDIPlus_BitmapCreateFromFile($sImg)
	Local $hBit2 = _GDIPlus_BitmapCloneArea($hBit, 90 + $aMax[0] + (($aPos2[2] - $aPos[0]) / 2) + $xSmesh, 190 + $aMax[1] + (($aPos2[3] - $aPos[1]) / 2) + 10 + $ySmesh, $oEl.width + 20, $oEl.height + 20)

	_GDIPlus_BitmapDispose($hBit)
	Local $sImg2 = _TempFile(@TempDir, '~', '.jpg')
	_GDIPlus_ImageSaveToFile($hBit2, $sImg2)

	_GDIPlus_BitmapDispose($hBit2)

	$sAnswer = _Captcha_ResolveFile($sImg2, IniRead(@ScriptDir & '\Settings.ini', 'AntiCaptcha', 'Key', ''), 0, 0, $iNumeric, 0, $iMin, $iMax)
	FileDelete($sImg)
	FileDelete($sImg2)
	Return $sAnswer
EndFunc   ;==>_Captcha_RecognizeByElement

Func _Captcha_ResolveFile($file_name, $captcha_key, $is_phrase = 0, $is_regsense = 0, $is_numeric = 0, $is_calc = 0, $min_len = 0, $max_len = 0, $is_russian = 0, $max_bid = 0, $bStore = False)
	;$ag = ObjCreate('AG_Tools.cl_CaptchaRec')
	;If @error Then
	RunWait('regsvr32.exe /S "' & @ScriptDir & '\AG_Tools.dll"')
	$ag = ObjCreate('AG_Tools.cl_CaptchaRec')
	If @error Then Return 'ERR Register'
	;EndIf
	$id = 0
	$text = 0
	$ret = 0
	$return = $ag.AG_RecognizeFile($captcha_key, $file_name, 0, '', 0, $id, $text, $ret, $is_phrase, $is_regsense, $is_numeric, $is_calc, $min_len, $max_len, $is_russian, $max_bid)
	If $bStore <> True Then FileDelete($file_name)
	If StringLeft($return, 3) = 'OK|' Then Return StringTrimLeft($return, 3)
	Return $text
EndFunc   ;==>_Captcha_ResolveFile

Func _ExitH()
	Exit
EndFunc   ;==>_ExitH

Func _Exit()
	_GDIPlus_Shutdown()
	If IsObj($oIE) Then _IEQuit($oIE)
EndFunc   ;==>_Exit

Func _ErrFunc($oError)
	; Do anything here.
	MsgBox(16, 'COM Error', @ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _
			@TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _
			@TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
			@TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _
			@TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _
			@TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
			@TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
			@TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
			@TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
			@TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF)
EndFunc   ;==>_ErrFunc

Видео с ошибкой: https://youtu.be/YBlwp13risk
 
Автор
A

at

Гость
Подниму тему, вопрос актуален. Прошу мемберов подсказать, где искать ошибку.
 
Верх