无论是模拟网页点击还是直接协议发包,都有其适用的环境。不同的需求选择不同的方案。如果只是简单的获取类似网页IP地址的需求,实际上协议发包是最简单的。但如果是用户名网页登陆等稍微复杂的登陆要求,则直接填写表单,并获取按钮元素来模拟点击这个方案来讲相对简单。但需求若稍微再变化一点,要求效率多线程,这个时候又是协议发包会作为首选,哪怕需要用户名网页登陆。没有最好的方案只有更合适的方案。这点很重要。

先说模拟网页点击方式,一般我采用的是继承MFC里面的CDHtmlDialog类自己命名为CWebLoginDlg,选择MFC并不是说有多好用,而是本人对于MFC使用更熟悉,学习成本更低,仅此而已。

模拟网页逻辑就是个状态机的处理,而状态的获取,一个可以通过获取网页源码判断特征字符串的方式,还有个可以通过XMLHttpRequest的回包判断数据的方式,再有也可以通过获取网页元素com组件对象是否存在的方式。

先说获取网页源码,基本原理是先获取网页DOC对象, 然后遍历DOC里面的元素,找到TAG为html的元素 get_outerHTML,c++代码如下:

std::wstring CWebLoginDlg::GetHtmlSource()
{CComPtr<IHTMLDocument2> sphtmlDoc;CComPtr<IHTMLElementCollection> pIHTMLElementCollect;GetDHtmlDocument(&sphtmlDoc);if (!sphtmlDoc){return L"";}sphtmlDoc->get_all(&pIHTMLElementCollect);long iCount;pIHTMLElementCollect->get_length(&iCount);CComBSTR data;for (int i = 0; i < iCount; i++){CComVariant v3,v4;v3=(long)i;v4.vt=VT_I4;v4=(long)0;CComPtr<IDispatch> pDisp;HRESULT hr = pIHTMLElementCollect->item(v3,v4,&pDisp);if (!SUCCEEDED(hr)){continue;}CComQIPtr<IHTMLElement, &IID_IHTMLElement> pHTMLElement(pDisp);if(pHTMLElement == NULL){continue;}CComBSTR strTagName;hr = pHTMLElement->get_tagName(&strTagName);if(!SUCCEEDED(hr)){continue;}CString strTag=strTagName;strTag.MakeLower();if(strTag!="html"){continue;}hr = pHTMLElement->get_outerHTML(&data);if(!SUCCEEDED(hr)){return L"";}break;}std::wstring source = data.m_str;return source;
}

再说XMLHttpRequest, XMLHttpRequest是对ajax技术的实现,重点体现在包头的Content-Type字段,这个字段值为application/x-www-form-urlencoded,例如网页代码:

function syncGameInfoAgent () {$.ajax({url : "/api/web/syncGameInfoAgent",type : "GET",cache : false,async : false,success : function(data, textStatus, jqXHR) {}});}

这种方式的ajax还会多个X-Requested-With字段,值为XMLHttpRequest,回包数据都为json格式,还有一种网页代码:

var loadLoginInfo = function() {$.ajax({url : getDomain() + "rest/user",type : "GET",data : {"fields" : "isNameCheck,charCount,isBlocked,isGameBlocked,extAccountInfo"},cache : false,async : true,dataType : "jsonp",success : function(response) {  ...

这种方式ajax没有X-Requested_With字段,回包数据为网页数据。c++实现方式如下:

MSXML2::IXMLHTTPRequestPtr m_pIXMLHTTPRequest;m_pIXMLHTTPRequest.CreateInstance("Msxml2.XMLHTTP.6.0");std::wstring CWebLoginDlg::XMLHttpRequest( std::wstring url , std::string requestType/* = "GET"*/)
{BSTR bstrString = NULL;HRESULT hr=m_pIXMLHTTPRequest->open(requestType.c_str(), url.c_str(), false);SUCCEEDED(hr) ? 0 : throw hr;m_pIXMLHTTPRequest->setRequestHeader("X-Requested-With", "XMLHttpRequest"); //这里第二种情况则不能带有此字段m_pIXMLHTTPRequest->setRequestHeader("Content-Type", "application/x-www-form-urlencoded");hr=m_pIXMLHTTPRequest->send();SUCCEEDED(hr) ? 0 : throw hr;bstrString=m_pIXMLHTTPRequest->responseText; //第二种情况则m_pIXMLHTTPRequest->responseBodystd::wstring freePayString = bstrString;if (bstrString){SysFreeString(bstrString);bstrString = NULL;}return freePayString;
}

这里提供一个技巧,找到ajax代码的实现,可以先抓包得到http header里面的request url的url字符串,然后在脚本里面去查找字符串,一般字符串就在ajax代码

url : getDomain() + "rest/user"里面搜索到,搜索到后可以看代码对于返回值的处理,这样才好方便写逻辑。

最后说下获取网页元素,一般来说网页元素都会带有ID或者带有ClassName,例如网页代码:

<input type="password" id="pwd" name="password" class="user_pw" maxlength="16" size="12" autocomplete="off" title="???? ??">

如果想通过ID获取网页对象,简单的可以直接通过GetElement函数来实现,C++代码如下:

IHTMLElement *id = NULL;
this->GetElement(TEXT("id"), &id);

如果想通过ClassName类名来获取网页对象,C++代码如下:

CComQIPtr< IHTMLElement > CWebLoginDlg::GetElementByClassName( std::wstring className )
{CComPtr<IHTMLDocument2> pIHTMLDocument2;GetDHtmlDocument(&pIHTMLDocument2);HRESULT hr;  CComQIPtr< IHTMLElementCollection > spElementCollection;  hr = pIHTMLDocument2->get_all( &spElementCollection ); //取得表单集合  if ( FAILED( hr ) )  {ATLTRACE("获取集合 IHTMLElementCollection 错误");}  long nFormCount=0;hr = spElementCollection->get_length( &nFormCount );  if ( FAILED( hr ) )  {ATLTRACE("获取数目错误");}  IDispatch *pDisp = NULL;CComQIPtr< IHTMLElement > ret = pDisp;for(long i=0; i<nFormCount; i++)  {  pDisp = NULL;hr = spElementCollection->item( CComVariant( i ), CComVariant(), &pDisp );  if ( FAILED( hr ) )  {continue;}CComQIPtr< IHTMLElement > pElement = pDisp;pDisp->Release();CComBSTR varRet;hr = pElement->get_className(&varRet);if (FAILED(hr)){continue;}if (varRet == NULL){continue;}LPCTSTR lpName = OLE2CT( varRet );if (std::wstring(lpName) == className){ret = pElement;break;}}return ret;
}

以上就是模拟网页中获取网页状态的基本函数,有了这几个函数网页模拟方式的基本框架基本都可以搭建起来了。

模拟网页行为之实践篇相关推荐

  1. 模拟网页行为之实践篇三

    现在来谈下验证码图片的获取方式,带有验证码的地方都会附带有个刷新按钮,而刷新按钮的地方就是获取验证码网址代码.如果看过前面写的<模拟网页行为之工具篇>就会很容易定位到代码位置.定位到代码位 ...

  2. 模拟网页行为之实践篇二

    在模拟网页行为中,最常用的就是提交表单了,其次就是获取验证图片数据,再次hook网页中的js代码的实现. 先说具体的应用场景,简单的场景,如填写用户名密码登陆,这里就涉及到获取表单,填写表单数据,提交 ...

  3. 模拟网页行为之工具篇二

    先说360浏览器,打开开发者选项,可以看到界面提供了几个功能选项,如图: 这个图片的第一个搜索图标点中过后,再去选中网页你感兴趣的部分就可以在Element选项中跳转到你感兴趣的代码.也可以直接ctr ...

  4. 模拟网页行为之工具篇

    模拟网页行为最常见的包含模拟网页登陆,模拟提交表单,甚至可以拒绝网页第三方安全软件的加载等一些更酷的行为,这种行为不仅仅是减少了一些非常枯燥重复的过程,更重要的是提升了商业行为中的效率,甚至会给你直接 ...

  5. python判断网页密码加密方式_Python模拟网页中javascript加密与验证的相关处理

    在做网络爬虫的过程中你是否一些在这方面做的很好的网站,你向知道他是通过哪些相关的操作做出这么好的网站,以下就是文章的相关内容的具体介绍,希望你浏览完下面的内容会有所收获.Python模拟网页的java ...

  6. node.js如何模拟网页点击?

    可以使用 Node.js 和一个第三方库,如 Puppeteer,来模拟网页点击.Puppeteer 是一个 Node.js 库,它提供了一个高级 API,用于控制 Chrome 或 Chromium ...

  7. 模拟网页点击爬虫交管12123违章数据!违章信息及时处理!

    本次介绍怎么以模拟点击方式进入交管12123爬取车辆违章数据,本文直接讲解过程,使用的命令解释见上一篇文章.本文同<Python教程-模拟网页点击爬虫定位系统>同样为企业中实际的爬虫案例, ...

  8. c语言写自动填写表单提交,利用C语言实现POST数据包如此简单【模拟网页提交表单】...

    http://www.maben.com.cn/archives/212.html 利用C语言实现POST数据包如此简单[模拟网页提交表单] //*************************** ...

  9. 【学浪下载教程】06学浪模拟网页版登录,无需客户端和全局代理软件

    学浪最新版插件添加了模拟网页端的功能,让大家不再需要打开客户端和全局代理软件(Proxifier) 这个功能只限于谷歌无痕模式下面 使用步骤 1.点击谷歌安装包进行安装(自己有谷歌浏览器就不需要安装) ...

最新文章

  1. 超详细的CMD文件讲解
  2. BeetleX之XRPC远程委托调用
  3. 谈谈C#中的三个关键词new , virtual , override
  4. 机器学习中生成模型和判别模型
  5. coreboot学习10:coreboot第一阶段学习小结
  6. 可重入函数 与线程安全的区别与联系
  7. math.floor实现四舍五入
  8. structs 1.x 学习
  9. 需要压缩NTFS盘的情况有哪些?
  10. 汽车品牌如何运营用户?
  11. 用java写图形验证码,超级简单
  12. 解决lefse配置过程中遇到的问题
  13. Discuz X3.4模板创建与配置原理简介
  14. 【STM32】HAL库——ADC
  15. 十张图,看数据分析如何赋能销售
  16. 【计算机网络】Web应用的安全问题——概述
  17. COS操作 java实现
  18. Matlab信号添加噪声及信噪比SNR的计算
  19. 视频教程-ElasticSearch7.x集群搭建(es7)主从读写分离搭建教程-ELK
  20. 云顶之弈下累了 就来看看C/C++内存管理吧

热门文章

  1. Java面试知识点:多线程
  2. web.xml配置解释
  3. svg笔记----------path篇
  4. 『重构--改善既有代码的设计』读书笔记----Split Temporary Variable
  5. 单例模式小记【原创】
  6. SpringBoot笔记整理(二)
  7. HTML--注册页面案例
  8. html5+实现图片自动切换,js图片自动切换效果处理代码
  9. c语言实现图像拼接程序,opencv2实现10张图像上下左右拼接融合分享!
  10. c++函数为什么带imp_二次函数含参最值问题,老师怎么讲学生都不明白,试试这九张动图...