引言
想给自己之前写的网页小说爬虫程序更新换代,之前一直是用winform的形式写的程序,因此这一次更新打算把UI换成WPF(因为听说WPF很漂亮),顺便也以此引入WPF的学习。
那么作为网页爬虫程序,最重要的就是html源码的获取了,通常的获取方式有几种:HttpWebRequest、WebRequest、WebClient、WebBrowser等。由于我这里写的爬虫软件针对的网站需要先登录才能看到小说内容,而我一次爬取的内容不多都是短篇小说,因此不需要考虑到爬取的速度,因此自然是打算使用WebBrowser来实现登陆后获取网页源码。而为了加快爬取速度我考虑多开几个WebBrowser线程,同时对多个页面进行采集,暂时不知道这个思路是否能够实现,这是后话了。(题外话,如果你要快速爬取大量网页,可以考虑使用WebClient,若有登录需求则进行模拟登录记录cookie,不过这样挺麻烦的)
问题
新建WPF项目后,第一件事就是吧WebBrowser控件拖一个到窗口中,由于我熟悉网站开发,因此xaml对我来说倒不是什么难事。可是在获取网页源代码这一步就坑爹了,WPF中WebBrowser的属性和方法似乎没有能够获取html 的!
实践
遇到问题先问搜索引擎,然而网上大家似乎都没有类似需求,全是WPF中如何用webbrowser操作html元素的,大概就是通过IHTMLElement接口操作DOM。不过既然都操作了DOM,那么获取html也是没问题的了。
1.引用中添加Microsoft.mshtml.dll
在中找到需要引用的项目
2.操作Html
之后就可以用HTMLDocument来操作Html了,记得要引用命名空间:mshtml。之后的内容以代码的形式贴上。
using mshtml; …… webBrowser.Navigate("http://www.baidu.com/"); // ……等待网页加载…… HTMLDocument doc = this.wb3.Document as HTMLDocument; //获取body内的html代码 string html = doc.body.innerHTML; //暂时没搞明白应该怎么获取所有的html代码 //根据ID获取元素 //根据id获得input IHTMLElement inputSearch = (IHTMLElement)doc.all.item("kw"); //为input设置value属性 inputSearch.setAttribute("value","设置搜索内容"); //获得搜索按钮 IHTMLElement submitSearch = (IHTMLElement)doc.all.item("su"); //点击按钮 submitSearch.click(); //获取窗体 mshtml.IHTMLWindow2 window = (mshtml.IHTMLWindow2)doc.parentWindow; //注入javascript window.execScript("alert(123);", "javascript"); //注入禁止弹窗等 window.execScript("function alert(){return;}", "javascript"); window.execScript("function confirm(){return;}", "javascript"); //第二次的alert将不会执行 window.execScript("alert(456);", "javascript");
/// <summary> /// 这个方法据说可以屏蔽掉JS,在Navigated事件中调用,未测试 /// </summary> /// <param name="wb"></param> /// <param name="Hide"></param> public void HideScriptErrors(WebBrowser wb, bool Hide) { FieldInfo fiComWebBrowser = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic); if (fiComWebBrowser == null) return; object objComWebBrowser = fiComWebBrowser.GetValue(wb); if (objComWebBrowser == null) return; objComWebBrowser.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, objComWebBrowser, new object[] { Hide }); }