[自动登录]|[模拟鼠标]|[自动投票]|[填写表单]

注意这里的核心是得到IHTMLDocument2 *,继而得到IHTMLElementCollection * objAllElement
我第一次是用ChtmlView做的,很简单:
    IHTMLElementCollection *objAllElement=NULL;
    IHTMLDocument2 *objDocument=NULL;
    objDocument=(IHTMLDocument2 *)this->GetHtmlDocument();; //由控件得到IHTMLDocument2接口指针
    objDocument->get_all(&objAllElement); //得到网页所有元素的集合
另外要注意的就是那个CComBSTR/CComVariant还需要学习。


[自动登录]|[模拟鼠标]|[自动投票]|[填写表单]

每天登录签到确实挺麻烦的:
1)打开网页,登录,经过一些步骤进入签到框,然后点击。。。
2)有的时候会忘了签退,这可要扣饭补地。。。
3)啥时候有急事儿,可以让他自己签退。。。

所以,我就看了一些自动填写表单,自动投票机的程序;发现在MFC中可以利用一些控件和接口来实现。实际上,采用模拟鼠标的方法就不用任何接口了, 只需要把操作步骤给程序;但是这样需要去计算那些控件的坐标,同时模拟的还有键盘输入等,总而言之,虽然易懂,却是繁琐。所以,这里采用接口。

1)头文件 #include "mshtml.h" 库 #pragma    comment(lib,"Wininet.lib")
2)控件 MS Web Browser变量 CWebBrowser m_WebBrowser
3)利用WebBrowser可以得到网页的内容,然后采用它的GetDocument方法得到网页文件;再把文件中的元素取出来,就可以操作这些元素了,比如填写表狂,点击按钮等。

// Connect the website
CString szConnectString = http://www.xxx.com/xxx.aspx;
m_WebBrowser.Navigate(szConnectString,NULL,NULL,NULL,NULL);

// Get the doc and elments
IDispatch * pDispatch = NULL;
IHTMLDocument2 * pDoc = NULL;
IHTMLElementCollection * objAllElement = NULL; // element collections
long nElementCount; // the count of elements

pDispatch = m_WebBrowser.GetDocument();
ASSERT(pDispatch);
HRESULT hr = pDispatch->QueryInterface(IID_IHTMLDocument2,(void**)&pDoc);
pDoc->get_all(&objAllElement);
ASSERT(objAllElement);

objAllElement->get_length(&nElementCount);

// Handle each element
VARIANT name;
name.vt = VT_I4;
for(int i = 0;i < nElementCount;i ++)
{
name.lVal = i;
IDispatch * pDispatch = NULL;
objAllElement->item(name,name,&pDispatch);
IHTMLElement* spElement = NULL;
pDispatch->QueryInterface(IID_IHTMLElement, (void**)&spElement);

// Attibute
CComVariant varAttribute;
CComBSTR bstrName("NAME");
CComBSTR bstrValue;

spElement->getAttribute(bstrName,0,&varAttribute);
if (SUCCEEDED(varAttribute.ChangeType(VT_BSTR)))
{
   bstrValue = varAttribute.bstrVal;
   if (bstrValue == _T("id"))
   {
    bstrValue = _T(szUser.GetBuffer(0)); // szUser是用户名
    spElement->put_innerText(bstrValue);
   }
   else if(bstrValue == _T("passwd"))
   {
    bstrValue = _T(szPass.GetBuffer(0));// szPass是密码
    spElement->put_innerText(bstrValue);
   }
}
// Click
bstrName = _T("VALUE");
spElement->getAttribute(bstrName,0,&varAttribute);
if (SUCCEEDED(varAttribute.ChangeType(VT_BSTR)))
{
   bstrValue = varAttribute.bstrVal;
   if (bstrValue == _T("登录"))// 这里是个按钮,如果是个图标也做类似的处理
   {
    spElement->click();
   }
}     
spElement->Release();
}

其它的步骤都类似了,比如进入某个填表的网页,也是先Navigate->GetDoc->GetElements->...,这样就完成自动登录,自动。。。了。


这是我写的 可以运行哦

  1. {
  2.     // TODO: Add your command handler code here
  3.     // TODO: Add your command update UI handler code here
  4.     using namespace std;
  5.     ofstream pFile(_T("C:/MYTXT.txt"));
  6.     IHTMLElementCollection *objAllElement=NULL;
  7.     IHTMLDocument2 *objDocument=NULL;
  8.     objDocument=(IHTMLDocument2 *)this->GetHtmlDocument();; //由控件得到IHTMLDocument2接口指针
  9.     objDocument->get_all(&objAllElement); //得到网页所有元素的集合
  10.     IHTMLElement * pElem = NULL; 
  11.     VARIANT name;
  12.     CComBSTR tag;
  13.     long  a;
  14.     objAllElement->get_length(&a);

  15.     name.vt=VT_I4;
  16.     IHTMLElement* spElement;
  17.     for(int i=0;i//遍历所有元素
  18.     {
  19.         name.lVal = i;

  20.         IDispatch * pDispatch=NULL;
  21.         objAllElement->item(name,name,&pDispatch);

  22.         pDispatch->QueryInterface(IID_IHTMLElement, (void**)&spElement);
  23.         /*
  24.         CComBSTR tag;
  25.         //spElement->get_outerText(&tag);
  26.         //spElement->get_innerText(&tag);
  27.         //spElement->toString(&tag);
  28.         //spElement->get_tagName(&tag);
  29.         //spElement->get_title(&tag);
  30.         CComVariant   ve2;
  31.         CComBSTR bstrValue; 
  32.         spElement-> getAttribute(CComBSTR("name"),0,&ve2);
  33.         if (SUCCEEDED(ve2.ChangeType(VT_BSTR)))
  34.         { //ve2.ChangeType(VT_BSTR);   
  35.         //CString ss(ve2.bstrVal);
  36.         bstrValue=ve2.bstrVal;
  37.         if (bstrValue == _T("wd"))
  38.         {
  39.         pFile<<"wd"<
  40.         }

  41.         }

  42.         //CString ss;

  43.         //if(ss=="")
  44.         // spElement->click();
  45.         //MessageBox((LPCSTR)ss);
  46.         }
  47.         //CComPtr pDisp;
  48.         //pobjAllElement->item(COleVariant(strName),COleVariant((long)0),&pDisp);
  49.         //CComQIPtrpElement;
  50.         /*
  51.         CComPtr pDisp;
  52.         CString strName="wd";
  53.         objAllElement->item(COleVariant(strName),COleVariant((long)0),&pDisp);
  54.         CComQIPtrpElement;
  55.         if(pDisp==NULL)
  56.         {
  57.         AfxMessageBox(strName + "没有找到!");
  58.         }
  59.         else
  60.         {
  61.         pElement=pDisp;
  62.         //pElement->click();
  63.         }*/

  64.         CComVariant varAttribute;
  65.         CComBSTR bstrName("name");
  66.         CComBSTR bstrValue;

  67.         spElement->getAttribute(bstrName,0,&varAttribute);
  68.         if (SUCCEEDED(varAttribute.ChangeType(VT_BSTR)))
  69.         {
  70.             bstrValue = varAttribute.bstrVal;
  71.             if (bstrValue == _T("wd"))
  72.             {
  73.                 bstrValue = _T("Yeah!成功了!"); // szUser是用户名
  74.                 spElement->put_innerText(bstrValue);
  75.             }
  76.         }
  77.         // Click
  78.         bstrName = _T("value");
  79.         spElement->getAttribute(bstrName,0,&varAttribute);
  80.         if (SUCCEEDED(varAttribute.ChangeType(VT_BSTR)))
  81.         {
  82.             bstrValue = varAttribute.bstrVal;
  83.             if (bstrValue == _T("百度一下"))// 这里是个按钮,如果是个图标也做类似的处理
  84.             {
  85.                 spElement->click();
  86.             }
  87.         }     

  88.     }

  89.     //ATLTRACE(L"%s",ve2.bstrVal);
  90.     spElement->Release();
  91. }

千方百计得到IHTMLDocument2的接口指针

根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。易索博客5n c-]"D Op

3V[HAjV[+Eip0  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
UR wRC(bj0        取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。易索博客G6zSr-T-G
  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。易索博客dfn!N'kIO
        取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
k3w�H5P_0  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
oZ"U,a;j0        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: 易索博客!?R2N3fx ^XBL)R)h/Q'g

cc^#?xkmmA&c3_W0CComPtr < IOleContainer > spContainer;
6/N(I-}e(P0m_spClientSite->GetContainer( &spContainer );
b,lT2~.WH0CComQIPtr < IHTMLDocument2 > spDoc = spContainer;易索博客Q'cv F"g)|Y
if ( spDoc )易索博客$R l4O/vx6o+JjJ$S}
{易索博客c0VJZ7u/`B$/
     // 已经得到了 IHTMLDocument2 的接口指针易索博客u4m kOJ[8^1jz,Ys9W
}


你可能感兴趣的:(webbrowser,null,mfc,文档,浏览器,browser)