分享

网页内容获取

 金员外1979 2017-04-08
假设m_browser是CWebBrowser2类型的变量,m_url是包含有ajax内容的网址,str_text是CString变量,执行如下代码
C/C++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
VARIANT flag;
flag.vt = VT_I4;
flag.iVal = navNoHistory | navNoReadFromCache | navNoWriteToCache;
m_browser.Navigate(m_url, &flag, NULL, NULL, NULL);
m_browser.put_Silent(TRUE);
MSG msg;
DWORD dwTimeStarted = ::GetTickCount();
for (int i = 0; i != 3; ++i)
{
    while (1000 > ::GetTickCount() - dwTimeStarted)
    {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
}
BSTR bstr;
HRESULT hResult = S_OK;
IHTMLElement* pElement1 = NULL;
IHTMLElement* pElement2 = NULL;
IHTMLDocument2* pDoc = (IHTMLDocument2*)m_browser.get_Document();
if (NULL != pDoc)
{
    hResult = pDoc->get_body(&pElement1);
    if (S_OK == hResult && NULL != pElement1)
    {
        hResult = pElement1->get_parentElement(&pElement2);
        if (S_OK == hResult && NULL != pElement2)
        {
            hResult = pElement2->get_outerHTML(&bstr);
            if (S_OK == hResult)
            {
                pDoc->Release();
                pDoc = NULL;
                pElement1->Release();
                pElement1 = NULL;
                pElement2->Release();
                pElement2 = NULL;
            }
        }
    }
}
else
{
    if (NULL != pDoc)
    {
        pDoc->Release();
        pDoc = NULL;
    }
    if (NULL != pElement1)
    {
        pElement1->Release();
        pElement1 = NULL;
    }
    if (NULL != pElement2)
    {
        pElement2->Release();
        pElement2 = NULL;
    }
    return;
}
str_text = bstr;

如果执行成功,str_text就是m_url对应网页源代码,并且包含了ajax内容。
注意:
1、一定要执行
C/C++ code
1
2
pDoc->Release();
pDoc = NULL;

C/C++ code
1
2
pElement1->Release();
pElement1 = NULL;

C/C++ code
1
2
pElement2->Release();
pElement2 = NULL;

否则每次执行m_browser.Navigate(....)后,都会有严重的内存泄漏!!!
2、一定要在m_browser.Navigate(....)后让程序暂时执行一小段时间(比如3秒、4秒、5秒),这是因为Navigate()函数会立即返回,同时Web Browser控件才开始加载网页,接着代码会向下执行,如果不预留足够的时间,有非常大的概率导致m_browser.get_Document()执行失败,也就无法获取网页源代码。而代码段
C/C++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
MSG msg;
DWORD dwTimeStarted = ::GetTickCount();
for (int i = 0; i != 3; ++i)
{
    while (1000 > ::GetTickCount() - dwTimeStarted)
    {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
}

就是让程序暂停执行了大约3秒钟。更多有关该代码段,请搜索关键词“VC版DoEvents”。该代码段有两个缺点:在暂停时间内程序占用的CPU资源会升高很多、在暂停时间内导致程序不执行代码块BOOL CXXXDlg::PreTranslateMessage(MSG* pMsg)。
3、用定时器也可以达到让程序暂停执行一小段时间的效果,并且没有上述两个缺点。如何使用定时器,请搜索网上的教程。
oo2461166893
关注
oo2461166893
oo2461166893
本版等级:T1
#11 得分:0回复于: 2014-05-29 09:21:15
引用 9 楼 zengshirong 的回复:
可以分享下么,在VC++中使用Web Browser控件编程实现获取ajax内容的方法?

上面漏了一句代码,在
C/C++ code
1
str_text = bstr;

后面,一定要加上这句
C/C++ code
1
SysFreeString(bstr);

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多