文档章节

WebBrowser之获取跳转页面的Document接口源码

V雪落有声V
 V雪落有声V
发布于 2015/06/09 17:35
字数 1095
阅读 72
收藏 0

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 备注:本篇文章来自 vc驿站:http://www.cctry.com/thread-254314-1-1.html
// C、C++、VC++ 各种学习资源,免费教程,期待您的加入!
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

问题由来是这样的,今天一个会员问我一个问题,说从咱们VC驿站下载了一个源码,程序的功能主要是在对话框上面放置了一个WebBrowser控件,程序启动的时候默认调用这句代码:

m_web.Navigate(_T("https://www.baidu.com/s?wd=400电话"), NULL, NULL, NULL, NULL);

打开这个网址:

https://www.baidu.com/s?wd=400电话,如下图:

点击【获取测试】按钮之后,执行如下函数:

void CCctryDlg::OnBnClickedButton1()
{
        //----------------------------------------------------------------------------------
        CComQIPtr <IHTMLDocument2, &IID_IHTMLDocument2> spDoc1 = m_web.get_Document();

        IHTMLDocument3 *pDoc3 = NULL;
        HRESULT hr = spDoc1->QueryInterface(IID_IHTMLDocument3, (void **)&pDoc3);
        if (!pDoc3 && FAILED(hr)) return;

        CComPtr <IHTMLElement> pUserElement;
        CComBSTR idName(CT2OLE(_T("kw"))); //获取编辑框元素ID
        hr = pDoc3->getElementById(idName, &pUserElement);
        if (FAILED(hr) ||!pUserElement) return;

        pUserElement->put_innerText(CComBSTR("新网页")); //写入字符串

        CComPtr <IHTMLElement> pBtnElement;
        CComBSTR idBtnName(CT2OLE(_T("su")));//获取表单按钮的元素ID
        hr = pDoc3->getElementById(idBtnName, &pBtnElement);
        if (FAILED(hr) || !pBtnElement) return;
        pBtnElement->click(); //模拟点击百度按钮进行搜索

        //----------------------------------------------------------------------------------

        //获取点击百度按钮之后的所有链接
        Sleep(5000); //加载完毕新打开的网页

        //再次重新获取,但是得到的链接还是原来400电话里面的,而不是新网页里的。
        CComQIPtr <IHTMLDocument2, &IID_IHTMLDocument2> spDoc2 = m_web.get_Document();
        GetAllLinks(spDoc2);
}

简单解释一下:就是获取百度搜索框的接口,之后向里面输入关键字:“新网页”,之后再获取【百度一下】按钮的接口,调用这句话 pBtnElement->click(); 进行点击事件的触发,说白了,就是在当前页面中搜索 “新网页” 这个关键字。
之后,调用 Sleep(5000); 等待一会新页面加载完成,再次调用 m_web.get_Document(); 获取当前网页的 document 文档接口,然后调用 GetAllLinks(spDoc2); 函数分析出当前页面的所有搜索结果的URL链接,显示在软件下面的列表中,如下图:

但是,问题来了,大家仔细看上面的图,列表中显示的URL链接都是上一个网址搜索 “400电话” 关键字的结果,不是之后搜索的关键字 “新网页” 的网址链接,这是怎么回事儿呢?跟我们要的结果不一致啊。。。
我还特意调用了 Sleep(5000),等待了 5 秒钟 呢,怎么结果还是不对?

于是乎。。。东奔西走,谷歌搜索了一大堆,还是没找到结果,到微软官方MSDN也没发现什么猫腻,到底是怎么回事儿呢,正准备要放弃的时候,忽然灵感来了,想一想,WebBrowser 走的是当前的主界面的 UI 线程,所以,他访问网页的过程也是在这个主界面的线程中来执行的,那么我们 Sleep(5000); 就没有意义了,不仅会卡住主界面线程,也同时会卡住 WebBrowser。当程序调用完 GetAllLinks(spDoc2); 这条语句之后可能新页面还没加载完,所以获取子链接的结果肯定是上一个页面的。

于是按照这一思想,我把【获取测试】按钮响应函数中的以下几句话注释掉:

Sleep(5000); //加载完毕新打开的网页
CComQIPtr <IHTMLDocument2, &IID_IHTMLDocument2> spDoc2 = m_web.get_Document();
GetAllLinks(spDoc2);

即,不让他 Sleep 了,也不让他在当前的这个按钮的响应函数中去获取新页面中所有的子链接,直接触发【百度一下】按钮点击事件之后就完事儿了。
接着,我再界面上再添加一个按钮,命名为【再测试下】,在这个按钮的响应函数中添加如下代码:

CComQIPtr <IHTMLDocument2, &IID_IHTMLDocument2> spDoc2 = m_web.get_Document();
GetAllLinks(spDoc2);

即,在这个【再测试下】按钮的响应函数中进行获取新页面中的所有子链接,看看能否成功!结果呢?哈哈,当然是成功啦,如下图:

看到了吧,这回列表中显示的已经是新页面的网页子链接了。。。

好了,文章就写到这吧,希望其他遇到相同问题的网友看到这篇文章,少走弯路!

相关工程源码请到原帖下载:

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 备注:本篇文章来自 vc驿站:http://www.cctry.com/thread-254314-1-1.html
// C、C++、VC++ 各种学习资源,免费教程,期待您的加入!
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

本文转载自:http://www.cctry.com/thread-254314-1-1.html

共有 人打赏支持
V雪落有声V
粉丝 0
博文 2
码字总数 0
作品 0
包头
程序员
私信 提问
Winform下动态执行JavaScript脚本获取运行结果,谈谈网站的自动登录及资料获取操作

为了有效阻止恶意用户的攻击,一般登录都会采用验证码方式方式处理登录,类似QQ的很多产品的验证码处理,但在一些OA系统中,系统通过非对称加密方式来处理登录的密码信息,登录页面每次提供对...

长平狐
2012/06/11
506
0
.NET中WebBrowser控件内部页面的JS代码与外部C#代码的相互调用

今天为了应对一个工作中遇到的场景,研究了下使用.NET中自带的WebBrowser时内部的JS代码与外部的C#代码相互调用的问题 我的操作系统为Win7旗舰版,IDE版本为VS2012,.NET版本为4.5 经过测试我...

北风其凉
2016/03/19
576
0
放弃MVP-Android Flux 框架 RxFlux2 (三)使用

首先,说放弃 MVP,肯定是夸大其词了。MVP 很好,只是个人不习惯那么多的回调,更喜欢 Flux 这种单向数据流模式。希望大家能多多点赞,多多拍砖! demo源码RxFlux2 下面以 com.huyingbao.si...

coolfireApy
2017/11/10
0
0
怎样在window phone8 中通过webBrowser调用第三方验证登陆接口

怎样在window phone8 中通过webBrowser调用第三方验证登陆接口,完成登陆后wp拦截redirect_uri地址获取登陆信息,同时跳转到wp主页面(main.xaml)...

北京鸿米科技有限公司
2014/04/03
0
0
c#使用webBrowser,控制页面、提交表单的两种方法

一、第一种方法貌似网上很少有人提。。。。就是使用javascript去控制页面。 熟悉javascript的人知道,它主要是用来控制客户端浏览器上行为动作的语言。 用浏览器随便打开一个页面,在地址栏输...

晨曦之光
2012/05/16
364
0

没有更多内容

加载失败,请刷新页面

加载更多

《TCP/IP详解 卷1:协议》第3章 IP:网际协议

3.1 引言 IP是TCP/IP协议族中最为核心的协议。所有的TCP、UDP、ICMP及IGMP数据都以IP数据报格式传输(见图1-4)。许多刚开始接触TCP/IP的人对IP提供不可靠、无连接的数据报传送服务感到很奇怪...

开元中国2015
13分钟前
1
0
如何创建高质量的TypeScript声明文件(七) - 该做什么和不该做什么

转载 如何创建高质量的TypeScript声明文件(七) - 该做什么和不该做什么 该做什么和不该做什么 一般类型 数字,字符串,布尔值和对象 不要使用Number,String,Boolean或Object类型。 这些类型...

durban
30分钟前
1
0
(6)添加vue-cookie

#(6)添加vue-cookie 1 安装vue-cookie cnpm install --save vue-cookie 2 引入 在main.js中进行引入: import Vue from 'vue' //这句是原来就有的import VueCookie from 'vue-cookie'Vue......

neumeng
38分钟前
1
0
node安装cnpm

npm install -g cnpm --registry=https://registry.npm.taobao.org

笑丶笑
今天
4
0
OSChina 周三乱弹 —— 夜半回家,推门不动

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @胖达panda :分享陶晶莹/张雨生的单曲《我期待》 《我期待》- 陶晶莹/张雨生 手机党少年们想听歌,请使劲儿戳(这里) @cc_z :熬夜一时爽,...

小小编辑
今天
1K
16

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部