请教一下关于SHDocVw.InternetExplorer实时监听

时间:2021-05-19 22:37:44
以前是做java的对c#的webbrowse不是很了解,可能请教的问题比较小白。希望大神能帮帮忙。
需要对一个三层框架页面进行数据采集,保存到数据库并将需要的数据用打印机输出。
通过SHDocVw.InternetExplorer ie=shellWindow.Item(shellWindow.Count - 1);得到ie浏览器。得到浏览器后如何实时的对页面进行监听,对所有元素添加鼠标按下监听。
尝试着用定时器不断刷行IhtmlDocument,使用activeElement。但当页面中checkbox选中后。后面的代码被无限执行。
不用定时器。页面只执行第一个触发的元素,后面的元素事件就没有响应。
请教一下大神这里该如何处理?哪里有比较详细的材料。度娘已经试过没有找到合适的材料。

谢谢了。

9 个解决方案

#1


如果你是做网页抓取
还是要使用httprequest,而不是webbrowse,更不是ie
c#本身就可以实现ie的功能,发送get或post请求直接得到数据,而不是从其它第三方软件里面抓

#2


好比你要做以太网TCP,IP通信,你就应该使用socket,而不是先打开另一个程序实现通信,然后你再抓网卡数据包
如果你要做串口通信,你就应该使用SerialPort,而不是打开串口调试助手,然后从串口调试助手的界面里抓文本

#3


引用 楼主 CXL88688 的回复:
以前是做java的对c#的webbrowse不是很了解,可能请教的问题比较小白。希望大神能帮帮忙。
需要对一个三层框架页面进行数据采集,保存到数据库并将需要的数据用打印机输出。
通过SHDocVw.InternetExplorer ie=shellWindow.Item(shellWindow.Count - 1);得到ie浏览器。得到浏览器后如何实时的对页面进行监听,对所有元素添加鼠标按下监听。
尝试着用定时器不断刷行IhtmlDocument,使用activeElement。但当页面中checkbox选中后。后面的代码被无限执行。
不用定时器。页面只执行第一个触发的元素,后面的元素事件就没有响应。
请教一下大神这里该如何处理?哪里有比较详细的材料。度娘已经试过没有找到合适的材料。

谢谢了。


事件里面要用委托才行。

#4


还是要使用httprequest,而不是webbrowse,更不是ie
c#本身就可以实现ie的功能,发送get或post请求直接得到数据,而不是从其它第三方软件里面抓
-------------------------------------------------------------------------------------------------------------------------------
我需要对页面的相关table数据进行抓取,并对新刷新的页面中input元素进行数据提示填写的功能,最后保存到本地,用热敏标签打印机打印。如果用httprequest只是得到值,提示功能就可能无法实现。或者我的想法不对还请Z65443344您指教。谢谢

=======================================================================================
这位大哥wyd1520可以稍微的说的详细一下吗?能给来一点代码?谢谢了。

感谢Z65443344和wyd1520回复,谢谢! 请教一下关于SHDocVw.InternetExplorer实时监听

#5


刚才度娘了一下事件里面要用委托,wyd1520您的意思不会是用一个鼠标的全局钩子监听吗?这个方法是我最开始的想法。因为某种原因放弃。可以做到对Ie浏览器内的鼠标监听吗?

#6


引用 5 楼 CXL88688 的回复:
刚才度娘了一下事件里面要用委托,wyd1520您的意思不会是用一个鼠标的全局钩子监听吗?这个方法是我最开始的想法。因为某种原因放弃。可以做到对Ie浏览器内的鼠标监听吗?



这里监听IE的Click事件,要这么写,不过这也有一个问题会造成IE的里面的HTML相应的事件没法执行,




 ((mshtml.HTMLDocumentEvents2_Event)Doc).onclick += new HTMLDocumentEvents2_onclickEventHandler(Program_onclick);



  private bool Program_onclick(IHTMLEventObj e)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(() => {
          
                    InvokeShow(string.Format("TagName:{0},InnserText:{1}", e.srcElement.tagName, e.srcElement.innerText)); <--
                }));
                
            }
            return true;
        }




第二种只是纯监听Click事件,这样就不会像上面那样,可以取到鼠标点击了哪个元素



 public delegate void DOMEvent(mshtml.IHTMLEventObj e);

    public class DOMEventHandler

    {

        public DOMEvent Handler;

        DispHTMLDocument Document;

        public DOMEventHandler(DispHTMLDocument doc)

        {

            this.Document = doc;

        }

        [DispId(0)]
        public void Call()
        {
            Handler(Document.parentWindow.@event);
        }

    }



   mshtml.DispHTMLDocument disp = ie.Document as DispHTMLDocument;
   DOMEventHandler onmousedownhandler = new DOMEventHandler(disp);
                    onmousedownhandler.Handler += new DOMEvent(Mouse_Down);
                    disp.onmousedown = onmousedownhandler;



 public void Mouse_Down(mshtml.IHTMLEventObj e)
        {

         
            if (System.Windows.Forms.Application.OpenForms.Count > 0) 跟上面一样这里要用委托 要不然会提示夸线程异常
            {
                System.Windows.Forms.Form frm = System.Windows.Forms.Application.OpenForms.Cast<System.Windows.Forms.Form>().First();
                if (frm.InvokeRequired)
                {
                    frm.Invoke(new Action(() =>
                    {
                        OnHandler(Document.parentWindow.@event);
                    }));
                }
            }

        }

#7


要这么写


 [ComVisible(true)] 
    public class HTMLEventHandler
    {
        public  HTMLEvent OnHandler;
        private HTMLDocument Document;

        public HTMLEventHandler(HTMLDocument doc)
        {
            this.Document = doc;
        }

        [DispId(0)]
        public void Call()
        {

            if (System.Windows.Forms.Application.OpenForms.Count > 0)
            {
                System.Windows.Forms.Form frm = System.Windows.Forms.Application.OpenForms.Cast<System.Windows.Forms.Form>().First();
                if (frm.InvokeRequired)
                {
                    frm.Invoke(new Action(() =>
                    {
                        OnHandler(Document.parentWindow.@event);
                    }));
                }
            }
            
        }
    }

#8


你的思路就错了,应该用BHO,而不是进程外访问。

#9


谢谢。wyd1520 提供的代码。测试后可以使用。也正是我需要的,十分感谢。
稍后有不明白的地方还要麻烦您一下。
===============================================
谢谢devmiao建议,刚刚度娘了一下BHO貌似有我用到的功能。稍后学习一下。您有BHO相关材料吗,能给我一份吗?
可以的话发我邮箱feilong322@163.com谢谢
==============================================
感谢Z65443344,wyd1520,devmiao帮助。

#1


如果你是做网页抓取
还是要使用httprequest,而不是webbrowse,更不是ie
c#本身就可以实现ie的功能,发送get或post请求直接得到数据,而不是从其它第三方软件里面抓

#2


好比你要做以太网TCP,IP通信,你就应该使用socket,而不是先打开另一个程序实现通信,然后你再抓网卡数据包
如果你要做串口通信,你就应该使用SerialPort,而不是打开串口调试助手,然后从串口调试助手的界面里抓文本

#3


引用 楼主 CXL88688 的回复:
以前是做java的对c#的webbrowse不是很了解,可能请教的问题比较小白。希望大神能帮帮忙。
需要对一个三层框架页面进行数据采集,保存到数据库并将需要的数据用打印机输出。
通过SHDocVw.InternetExplorer ie=shellWindow.Item(shellWindow.Count - 1);得到ie浏览器。得到浏览器后如何实时的对页面进行监听,对所有元素添加鼠标按下监听。
尝试着用定时器不断刷行IhtmlDocument,使用activeElement。但当页面中checkbox选中后。后面的代码被无限执行。
不用定时器。页面只执行第一个触发的元素,后面的元素事件就没有响应。
请教一下大神这里该如何处理?哪里有比较详细的材料。度娘已经试过没有找到合适的材料。

谢谢了。


事件里面要用委托才行。

#4


还是要使用httprequest,而不是webbrowse,更不是ie
c#本身就可以实现ie的功能,发送get或post请求直接得到数据,而不是从其它第三方软件里面抓
-------------------------------------------------------------------------------------------------------------------------------
我需要对页面的相关table数据进行抓取,并对新刷新的页面中input元素进行数据提示填写的功能,最后保存到本地,用热敏标签打印机打印。如果用httprequest只是得到值,提示功能就可能无法实现。或者我的想法不对还请Z65443344您指教。谢谢

=======================================================================================
这位大哥wyd1520可以稍微的说的详细一下吗?能给来一点代码?谢谢了。

感谢Z65443344和wyd1520回复,谢谢! 请教一下关于SHDocVw.InternetExplorer实时监听

#5


刚才度娘了一下事件里面要用委托,wyd1520您的意思不会是用一个鼠标的全局钩子监听吗?这个方法是我最开始的想法。因为某种原因放弃。可以做到对Ie浏览器内的鼠标监听吗?

#6


引用 5 楼 CXL88688 的回复:
刚才度娘了一下事件里面要用委托,wyd1520您的意思不会是用一个鼠标的全局钩子监听吗?这个方法是我最开始的想法。因为某种原因放弃。可以做到对Ie浏览器内的鼠标监听吗?



这里监听IE的Click事件,要这么写,不过这也有一个问题会造成IE的里面的HTML相应的事件没法执行,




 ((mshtml.HTMLDocumentEvents2_Event)Doc).onclick += new HTMLDocumentEvents2_onclickEventHandler(Program_onclick);



  private bool Program_onclick(IHTMLEventObj e)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(() => {
          
                    InvokeShow(string.Format("TagName:{0},InnserText:{1}", e.srcElement.tagName, e.srcElement.innerText)); <--
                }));
                
            }
            return true;
        }




第二种只是纯监听Click事件,这样就不会像上面那样,可以取到鼠标点击了哪个元素



 public delegate void DOMEvent(mshtml.IHTMLEventObj e);

    public class DOMEventHandler

    {

        public DOMEvent Handler;

        DispHTMLDocument Document;

        public DOMEventHandler(DispHTMLDocument doc)

        {

            this.Document = doc;

        }

        [DispId(0)]
        public void Call()
        {
            Handler(Document.parentWindow.@event);
        }

    }



   mshtml.DispHTMLDocument disp = ie.Document as DispHTMLDocument;
   DOMEventHandler onmousedownhandler = new DOMEventHandler(disp);
                    onmousedownhandler.Handler += new DOMEvent(Mouse_Down);
                    disp.onmousedown = onmousedownhandler;



 public void Mouse_Down(mshtml.IHTMLEventObj e)
        {

         
            if (System.Windows.Forms.Application.OpenForms.Count > 0) 跟上面一样这里要用委托 要不然会提示夸线程异常
            {
                System.Windows.Forms.Form frm = System.Windows.Forms.Application.OpenForms.Cast<System.Windows.Forms.Form>().First();
                if (frm.InvokeRequired)
                {
                    frm.Invoke(new Action(() =>
                    {
                        OnHandler(Document.parentWindow.@event);
                    }));
                }
            }

        }

#7


要这么写


 [ComVisible(true)] 
    public class HTMLEventHandler
    {
        public  HTMLEvent OnHandler;
        private HTMLDocument Document;

        public HTMLEventHandler(HTMLDocument doc)
        {
            this.Document = doc;
        }

        [DispId(0)]
        public void Call()
        {

            if (System.Windows.Forms.Application.OpenForms.Count > 0)
            {
                System.Windows.Forms.Form frm = System.Windows.Forms.Application.OpenForms.Cast<System.Windows.Forms.Form>().First();
                if (frm.InvokeRequired)
                {
                    frm.Invoke(new Action(() =>
                    {
                        OnHandler(Document.parentWindow.@event);
                    }));
                }
            }
            
        }
    }

#8


你的思路就错了,应该用BHO,而不是进程外访问。

#9


谢谢。wyd1520 提供的代码。测试后可以使用。也正是我需要的,十分感谢。
稍后有不明白的地方还要麻烦您一下。
===============================================
谢谢devmiao建议,刚刚度娘了一下BHO貌似有我用到的功能。稍后学习一下。您有BHO相关材料吗,能给我一份吗?
可以的话发我邮箱feilong322@163.com谢谢
==============================================
感谢Z65443344,wyd1520,devmiao帮助。