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

利用 MSHTML 介面提取網頁所有超連結 (IHTMLDocument2 實作)

     編輯:關於VC++

核心原理

載入網頁的 IWebBrowser2 控制項內部持有文件物件模型 (DOM)。透過 IHTMLDocument2::get_links 取得 IHTMLElementCollection,列舉其中的 IHTMLAnchorElement,即可取得每個 <a> 標籤的 href、hostname 等屬性。

完整實作代碼 (ATL/MFC 智慧指標版)

void CMyClass::ExtractAllLinks()
{
    // 清空現有列表
    int n = m_LinksList.GetItemCount();
    for (int i = 0; i < n; ++i) {
        IWebBrowser2* pBr = (IWebBrowser2*)m_LinksList.GetItemData(i);
        if (pBr) pBr->Release();
    }
    m_LinksList.DeleteAllItems();
    m_LinksNum = 0;
    UpdateData(FALSE);

    if (!m_spSHWinds) return; // IShellWindows 介面指標

    long count = 0;
    m_spSHWinds->get_Count(&count);
    for (long i = 0; i < count; ++i) {
        _variant_t vIdx(i);
        IDispatchPtr spDisp;
        m_spSHWinds->Item(vIdx, &spDisp);
        if (!spDisp) continue;

        SHDocVw::IWebBrowser2Ptr spBrowser(spDisp); // QueryInterface
        if (!spBrowser) continue;

        // 取得文件物件
        IDispatchPtr spDocDisp;
        if (FAILED(spBrowser->get_Document(&spDocDisp))) continue;
        CComQIPtr pDoc2(spDocDisp);
        if (!pDoc2) continue;

        // 取得連結集合
        CComPtr spLinks;
        if (FAILED(pDoc2->get_links(&spLinks))) continue;

        long linkCount = 0;
        spLinks->get_length(&linkCount);
        if (linkCount == 0) continue;

        m_LinksNum += linkCount;
        UpdateData(FALSE);

        for (long j = 0; j < linkCount; ++j) {
            _variant_t vIdx2(j), vIdx3(j);
            IDispatchPtr spElemDisp;
            if (FAILED(spLinks->item(vIdx2, vIdx3, &spElemDisp))) continue;

            CComQIPtr spAnchor(spElemDisp);
            if (!spAnchor) continue;

            BSTR bstrHref = NULL, bstrHost = NULL;
            spAnchor->get_href(&bstrHref);
            spAnchor->get_hostname(&bstrHost);

            TCHAR szBuf[2 * MAX_PATH] = {0};
            if (bstrHref) {
                _tcscpy_s(szBuf, _bstr_t(bstrHref));
                int nItem = m_LinksList.InsertItem(j, szBuf);
                m_LinksList.SetCheck(nItem, TRUE);
                SysFreeString(bstrHref);
            }
            if (bstrHost) {
                _tcscpy_s(szBuf, _bstr_t(bstrHost));
                if (_tcslen(szBuf))
                    m_LinksList.SetItemText(j, 1, szBuf);
                SysFreeString(bstrHost);
            }
        }
    }
}

關鍵技術點

  • ShellWindows 枚舉:IShellWindows 可列舉系統所有 IE/資源管理員視窗,適合做類似「網際快車」的全域連結抓取工具。
  • 智慧指標 (CComPtr, CComQIPtr, _variant_t, _bstr_t):自動管理 COM 參考計數、VARIANT/BSTR 生命週期,避免洩漏。
  • 跨執行緒單元 (STA):MSHTML 單元模型需在 UI 執行緒呼叫,否則需 CoMarshalInterThreadInterfaceInStream 封送。
  • 相容性:代碼在 VC7 (VS.NET 2003) + WinXP 編譯通過;VC6 需確認 mshtml.tlb 版本。

擴充應用

  • 抓取 IHTMLImgElement (get_images) 下載所有圖片。
  • 抓取 IHTMLScriptElement 分析頁面腳本。
  • 結合 IHTMLElement::get_innerHTML/outerHTML 做內容離線存檔。

原始碼下載

完整專案包含列表控制項顯示、勾選下載等功能:
本文配套源碼

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