文档章节

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

V雪落有声V
 V雪落有声V
发布于 2015/06/09 17:35
字数 1095
阅读 60
收藏 0
点赞 0
评论 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 ⋅ 0

delphi中Webbrowser

1.获得网页中变量值 htm中<script> var currID=123</script> 程序中可以这么调用 id := Form1.WebBrowser1.OleObject.Document.script.currID 值得说明的是,变量可以是javascript定义的,也可......

任远 ⋅ 2015/05/08 ⋅ 0

放弃MVP-Android Flux 框架 RxFlux2 (三)使用

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

coolfireApy ⋅ 2017/11/10 ⋅ 0

怎样在window phone8 中通过webBrowser调用第三方验证登陆接口

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

北京鸿米科技有限公司 ⋅ 2014/04/03 ⋅ 0

.NET中WebBrowser控件内部页面的JS代码与外部C#代码的相互调用

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

北风其凉 ⋅ 2016/03/19 ⋅ 0

通过JS组装表单

场景:例如我们做一个支付功能,肯定需要与第三方支付公司进行对接,比如【网关支付】是需要跳转到第三方的充值页面的,但是第三方只提供了后台接口,我们可以通过调用第三方的接口获取到我们...

zheng854938169 ⋅ 2017/05/09 ⋅ 0

WebBrowser.ExecWB的完整说明

<OBJECT classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0 id=WebBrowser width=0></OBJECT> <input name=Button .Click=document.all.WebBrowser.ExecWB(1,1) type=button val......

Cherish_you ⋅ 2012/04/23 ⋅ 0

DOM,DOCUMENT; BOM,WINDOW

这几个知识点,你真的都吃透了吗? # 先说 DOM: DOM 全称是 Document Object Model,也就是文档对象模型 DOM 就是针对 HTML 和 XML 提供的一个API,就是为了开发人员能操作 HTML 内容(比如...

果汁凉茶丶 ⋅ 01/06 ⋅ 0

WebBrowser控件使用技巧分享

在发布“淘宝登货员”时发现不少朋友对WebBrowser控件比较感兴趣,故在此分享一下使用心得。 首先分享一个WebBrowser的扩展类(此类所需的dll将在文章末尾提供下载),大家最好都使用这个类来...

老朱教授 ⋅ 2017/11/13 ⋅ 0

Web系统页面打印技术实现与分析

1 Web页面打印概述 应用WEB化,不论对开发商,还是对用户来说,实在是一种很经济的选择,因为基于WEB的应用,客户端的规则很简单,容易学习,容易维护,容易发布。在WEB系统中,打印的确是个...

程明卫 ⋅ 2011/09/13 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

说说javascript中的那些专业名词

DOM(Document Object Model) 文档对象模型 BOM(Browser Object Model) 浏览器对象模型 ECMA(European Computer Manufacturer's Association) 欧洲计算机制造商协会 W3C(World Wide Web Conso......

hang1989 ⋅ 36分钟前 ⋅ 0

Bootstrap Wizard 多步表单控件

废话 有一块需求是 有多步表单 点击下一步时触发验证一个范围内的表单,点击上一步或取消,清空表单并返回第一步,点击最后一步提交整个表单的 就找到了这个插件,本来自己写了一个原生的 fo...

无极之岚 ⋅ 52分钟前 ⋅ 0

如何利用Spring Cloud构建起自我修复型分布式系统

利用Netflix所打造的组件及各类大家熟知的工具,我们完全可以顺利应对由微服务以及分布式计算所带来的技术挑战。 在过去一年当中,微服务已经成为软件架构领域一个炙手可热的新名词,而且我们...

harries ⋅ 今天 ⋅ 0

临近实习前的感想

再过两星期就要开始新的一段实习了,想想去年的这个时候也在实习,心中不免思绪万千,也一直想写对2017做个总结,但一直迟迟没有下笔。 2017年的春节,我就开始准备开学后找份实习。那时候就...

无精疯 ⋅ 今天 ⋅ 0

Spring AOP(面向切面编程)

Spring AOP概念: Spring AOP 可以劫持一个执行的方法,在方法执行之前或之后添加额外的功能。通常情况下,AOP把项目中需要在多处用到的功能,比如日志、安全和事物等集中到一个类中处理,而...

霍淇滨 ⋅ 今天 ⋅ 0

人工智能、机器学习、数据挖掘以及数据分析有什么联系?

人工智能是目前炙手可热的一个领域,所有的互联网公司以及各路大迦们纷纷表态人工智能将是下一个时代的革命性技术,可与互联网、移动互联网时代的变更相媲美;AlphaGo在围棋领域战胜人类最顶...

董黎明 ⋅ 今天 ⋅ 0

使用 vue-cli 搭建项目

vue-cli 是一个官方发布 vue.js 项目脚手架,使用 vue-cli 可以快速创建 vue 项目,GitHub地址是:https://github.com/vuejs/vue-cli 一、 安装 node.js 首先需要安装node环境,可以直接到中...

初学者的优化 ⋅ 今天 ⋅ 0

设计模式 之 享元模式

设计模式 之 享元模式 定义 使用共享技术来有效地支持大量细粒度对象的复用 关键点:防止类多次创建,造成内存溢出; 使用享元模式来将内部状态与外部状态进行分离,在循环创建对象的环境下,...

GMarshal ⋅ 今天 ⋅ 0

SpringBoot集成Druid的最简单的小示例

参考网页 https://blog.csdn.net/king_is_everyone/article/details/53098350 建立maven工程 Pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM......

karma123 ⋅ 今天 ⋅ 0

Java虚拟机基本结构的简单记忆

Java堆:一般是放置实例化的对象的地方,堆分新生代和老年代空间,不断未被回收的对象越老,被放入老年代空间。分配最大堆空间:-Xmx 分配初始堆空间:-Xms,分配新生代空间:-Xmn,新生代的大小一...

算法之名 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部