模拟网页行为之实践篇二
生活随笔
收集整理的這篇文章主要介紹了
模拟网页行为之实践篇二
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在模擬網頁行為中,最常用的就是提交表單了,其次就是獲取驗證圖片數據,再次hook網頁中的js代碼的實現。
先說具體的應用場景,簡單的場景,如填寫用戶名密碼登陸,這里就涉及到獲取表單,填寫表單數據,提交表單三個過程。
在網頁數據中,表單的形式一般都會帶有名字,ID,提交的處理網頁的url和其擁有的幾個IHTMLInputElement元素,具體網頁代碼如下:
<form name="loginFrm1" id="loginFrm1" method="post" action="https://mlogin.plaync.com/login/signin"><input type="hidden" name="return_url" value="http://lineage.plaync.com/"><fieldset><legend>???</legend><div class="selectId"><select name="game_id"><option value="13">????</option><option value="31">????</option></select></div><div class="login_input"><input type="text" id="id" name="login_name" maxlength="64" size="12" class="user_id" autocomplete="off" title="??? ?? ??? ??"><input type="password" id="pwd" name="password" class="user_pw" maxlength="16" size="12" autocomplete="off" title="???? ??"><input type="button" name="login" value="???" class="submit"></div></fieldset><ul class="member"><li class="join"><a href="http://go.plaync.co.kr/Account/Join">????</a></li><li class="find"><a href="http://go.plaync.co.kr/Account/SearchAccount">??</a>/<a href="http://go.plaync.co.kr/Account/SearchPassword">??????</a></li></ul><div class="custom"><a class="new" href="http://lineage.plaync.com/service/freepay/index"><i></i>???????</a><a class="comming" href="http://lineage.plaync.com/service/returnbrave/index"><i></i>????????</a></div></form>可以看到,表單名字為loginFrm1,ID為loginFrm1,提交的url為https://mlogin.plaync.com/login/signin,擁有的幾個元素login_name, password,login。首先獲取表單,基本原理也是找到DOC,然后通過get_forms找到表單的集合,然后遍歷表單找到名字為loginfrm1的表單對象IHTMLFormElement將之返回。c++代碼如下:
CComQIPtr< IHTMLFormElement > CWebLoginDlg::GetFormByName( std::wstring name ) {IDispatch *pDisp = NULL;CComQIPtr< IHTMLFormElement > ret = pDisp;CComPtr<IHTMLDocument2> pIHTMLDocument2;GetDHtmlDocument(&pIHTMLDocument2);if (pIHTMLDocument2 == NULL){return ret;}HRESULT hr; CComBSTR bstrTitle; pIHTMLDocument2->get_title( &bstrTitle );CComQIPtr< IHTMLElementCollection > spElementCollection; hr = pIHTMLDocument2->get_forms( &spElementCollection ); //取得表單集合 if ( FAILED( hr ) ) {ATLTRACE("獲取表單的集合 IHTMLElementCollection 錯誤");} long nFormCount=0;hr = spElementCollection->get_length( &nFormCount ); if ( FAILED( hr ) ) {ATLTRACE("獲取表單數目錯誤");} for(long i=0; i<nFormCount; i++) { pDisp = NULL;hr = spElementCollection->item( CComVariant( i ), CComVariant(), &pDisp ); if ( FAILED( hr ) ) {continue;}CComQIPtr< IHTMLFormElement > spFormElement = pDisp;pDisp->Release();long nElemCount=0; hr = spFormElement->get_length( &nElemCount );if ( FAILED( hr ) ) {continue;}CComBSTR formName;hr = spFormElement->get_name(&formName);if (FAILED(hr)){continue;}LPCTSTR lpName = OLE2CT(formName);if (std::wstring(lpName) == name){ret = spFormElement;}}return ret; }其次填寫表單,基本原理是通過get_length獲取表單域個數,然后遍歷表單域元素,通過GetpropertyByName找到需要填寫的元素,然后用PutPropertyByName填寫表單值,具體c++實現如下:
void CWebLoginDlg::InputFormElement( CComQIPtr< IHTMLFormElement > spFormElement, std::map<std::wstring, std::wstring> formDataList ) {if (spFormElement != NULL){long nElemCount=0; HRESULT hr = spFormElement->get_length( &nElemCount );for(long j=0; j<nElemCount; j++) { CComDispatchDriver spInputElement; //取得第 j 項表單域 hr = spFormElement->item( CComVariant( j ), CComVariant(), &spInputElement ); if ( FAILED( hr ) ) continue;CComVariant vName,vVal,vType; //取得表單域的 名,值,類型 hr = spInputElement.GetPropertyByName( L"name", &vName ); if( FAILED( hr ) ) continue;hr = spInputElement.GetPropertyByName( L"value", &vVal ); if( FAILED( hr ) ) continue;hr = spInputElement.GetPropertyByName( L"type", &vType ); if( FAILED( hr ) ) continue; LPCTSTR lpName = vName.bstrVal? OLE2CT( vName.bstrVal ) : _T("NULL");LPCTSTR lpVal = vVal.bstrVal? OLE2CT( vVal.bstrVal ) : _T("NULL");LPCTSTR lpType = vType.bstrVal? OLE2CT( vType.bstrVal ) : _T("NULL");ATLTRACE(L"old name:%s, lpVal:%s lpType:%s", lpName, lpVal, lpType);if (formDataList.find(lpName) != formDataList.end()){CComVariant vContent(formDataList[lpName].c_str());spInputElement.PutPropertyByName(L"value", &vContent);}hr = spInputElement.GetPropertyByName( L"name", &vName ); if( FAILED( hr ) ) continue; hr = spInputElement.GetPropertyByName( L"value", &vVal ); if( FAILED( hr ) ) continue; hr = spInputElement.GetPropertyByName( L"type", &vType ); if( FAILED( hr ) ) continue; lpName = vName.bstrVal? OLE2CT( vName.bstrVal ) : _T("NULL");lpVal = vVal.bstrVal? OLE2CT( vVal.bstrVal ) : _T("NULL");lpType = vType.bstrVal? OLE2CT( vType.bstrVal ) : _T("NULL");ATLTRACE(L"new name:%s, lpVal:%s lpType:%s", lpName, lpVal, lpType);}} }最后提交表單,這個很簡單,首先找到提交按鈕對象,然后調用對象接口click,即可實現提交表單,具體c++代碼實現如下:
CComQIPtr< IHTMLElement > pButton = GetElementByClassName(L"login"); if (pButton != NULL) {ATLTRACE("dologin");pButton->click(); }
總結
以上是生活随笔為你收集整理的模拟网页行为之实践篇二的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汇编语言笔记(一):基础
- 下一篇: oracle转换请求无法实施,Oracl