首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

DOM 應用實戰:遍歷網頁表單元素、模擬操作與資料提取

     編輯:關於VC++

應用場景

需對 IE 開啟的網頁進行監控、模擬操作、動態提取使用者輸入、動態修改 DOM 內容等,核心在於取得 IHTMLDocument2 並遞迴遍歷 Frame/表單/元素樹。

DOM 階層架構

IWebBrowser2 / IHTMLWindow2 (容器)
    └─ IHTMLDocument2 (文件)
        ├─ IHTMLFramesCollection2 (Frame 集合)
        │   └─ IHTMLWindow2 (子 Frame 容器) → 遞迴
        └─ IHTMLElementCollection (表單/圖片/連結等集合)
            └─ IHTMLFormElement / IHTMLInputElement / ... (具體元素)

取得 IHTMLDocument2 的六種情境

情境方法
MFC CHtmlViewCHtmlView::GetHtmlDocument()
MFC CWebBrowser2 控件CWebBrowser2::GetDocument()
ATL ActiveX 控件IOleClientSite::GetContainer() → QI IHTMLDocument2
MFC ActiveX 控件COleControl::GetClientSite() → 同 ATL
獨立 IE 進程 (最常用)透過 IShellWindows 列舉所有殼層視窗,Item() → IWebBrowser2 → get_Document() → QI IHTMLDocument2
IE 控件嵌入他人視窗FindWindow/EnumChildWindows 找 Internet Explorer_Server 類別 → SendMessage(WM_HTML_GETOBJECT) → ObjectFromLresult()

關鍵程式碼片段

情境 5:IShellWindows 列舉 (範例程式採用)

#include <atlbase.h>
#include <mshtml.h>

void FindFromShell()
{
    CComPtr<IShellWindows> spShellWin;
    HRESULT hr = spShellWin.CoCreateInstance(CLSID_ShellWindows);
    if (FAILED(hr)) return;

    long nCount = 0;
    spShellWin->get_Count(&nCount);
    for (long i = 0; i < nCount; i++)
    {
        CComPtr<IDispatch> spDisp;
        hr = spShellWin->Item(CComVariant(i), &spDisp);
        if (FAILED(hr)) continue;

        CComQIPtr<IWebBrowser2> spBrowser(spDisp);
        if (!spBrowser) continue;

        hr = spBrowser->get_Document(&spDisp);
        if (FAILED(hr)) continue;

        CComQIPtr<IHTMLDocument2> spDoc(spDisp);
        if (!spDoc) continue;

        // 已取得 spDoc,可進入遍歷流程
        ProcessDocument(spDoc);
    }
}

遞迴處理 Frame

void ProcessDocument(IHTMLDocument2* pDoc)
{
    // 1. 處理 Frame 遞迴
    CComPtr<IHTMLFramesCollection2> spFrames;
    pDoc->get_frames(&spFrames);
    if (spFrames)
    {
        long len = 0;
        spFrames->get_length(&len);
        for (long i = 0; i < len; i++)
        {
            CComPtr<IDispatch> spFrameDisp;
            spFrames->item(CComVariant(i), CComVariant(), &spFrameDisp);
            CComQIPtr<IHTMLWindow2> spWin(spFrameDisp);
            if (spWin)
            {
                CComPtr<IDispatch> spChildDocDisp;
                spWin->get_document(&spChildDocDisp);
                CComQIPtr<IHTMLDocument2> spChildDoc(spChildDocDisp);
                if (spChildDoc) ProcessDocument(spChildDoc);
            }
        }
    }

    // 2. 列舉表單
    CComPtr<IHTMLElementCollection> spForms;
    pDoc->get_forms(&spForms);
    if (!spForms) return;

    long nFormCount = 0;
    spForms->get_length(&nFormCount);
    for (long i = 0; i < nFormCount; i++)
    {
        CComPtr<IDispatch> spFormDisp;
        spForms->item(CComVariant(i), CComVariant(), &spFormDisp);
        CComQIPtr<IHTMLFormElement> spForm(spFormDisp);
        if (!spForm) continue;

        // 3. 列舉表單元素
        CComPtr<IHTMLElementCollection> spElements;
        spForm->get_elements(&spElements);
        long nElemCount = 0;
        spElements->get_length(&nElemCount);

        for (long j = 0; j < nElemCount; j++)
        {
            CComDispatchDriver spElem; // ATL 智慧指標包裝 IDispatch
            spElements->item(CComVariant(j), CComVariant(), &spElem);

            CComVariant vName, vValue, vType;
            spElem.GetPropertyByName(L"name", &vName);
            spElem.GetPropertyByName(L"value", &vValue);
            spElem.GetPropertyByName(L"type", &vType);

            // 輸出或處理元素屬性
            wprintf(L"Form[%d] Elem[%d]: name=%s, value=%s, type=%s\n",
                i, j, vName.bstrVal, vValue.bstrVal, vType.bstrVal);
        }
    }
}

兩種元素型別判斷策略

  • 強型別 QI:CComQIPtr<IHTMLInputTextElement> 等,效率高、IntelliSense 友善,適合已知頁面結構。
  • IDispatch 晚期繫結:CComDispatchDriver::GetPropertyByName,通用性強、程式碼簡潔,適合通用爬蟲/監控工具 (本文採用)。

執行方式

  1. 先開啟數個含表單的網頁 (如登入頁、搜尋頁)。
  2. 執行本範例 EXE,主控台將列出所有偵測到的表單元素名稱、值、型別。

結語

掌握 IShellWindows + IHTMLDocument2 + 遞迴 Frame + CComDispatchDriver 即可構建強大的網頁自動化/監控工具。VC6 編譯通過,歡迎實作延伸。

本文配套完整原始碼可供下載。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved