程序设计实训-课程表管理系统项目中遇到的问题
这个项目,我是想在窗口创建的同时,爬取我们教务网的课程表,然后储存到数据库中,然后再根据需要,做各种查询。
目前还没写完,但是就以及遇到了很多棘手的问题,现记录一下,希望以后遇到有所借鉴。
1.HtmlElement对象再网页刷新或做其他的操作时,可能会失效,所以在使用HtmlElement对象前,最好再赋值。
2.如何将网页中的验证码图片,读取到pictureBox控件上
一开始想到的是用已知的验证码链接,然后再用request,代码如下:
//建立一个请求 WebRequest requ = new WebRequest.Create(url); WebResponse webres = requ.GetResponse(); Stream stream = webres.GetResponseStream(); //从流中获取图片 pictureBox1.Image = Image.FromStream(stream);
但是这样会导致图片与webbroswer1中的验证码不是同一个验证码,因为访问一次验证码图片的链接,就相当于获得一个新的验证码。
最后,用的是之前自己在网上找到的解决方案,代码如下:
using mshtml;//要先添加 microsoft.mshtml 的引用 private Image GetCodeImg(WebBrowser WebControlName, HtmlElement ImgeTag) { HTMLDocument hdoc = (HTMLDocument)WebControlName.Document.DomDocument; //获取网页body标签中的内容 HTMLBody hbody = (HTMLBody)hdoc.body; //创建一个接口 IHTMLControlRange hcr = (IHTMLControlRange)hbody.createControlRange(); //获取图片地址 IHTMLControlElement hImg = (IHTMLControlElement)ImgeTag.DomElement; //将图片添加到接口中 hcr.add(hImg); //将图片复制到内存 hcr.execCommand("Copy", false, null); //从粘贴板得到图片 Image CodeImage = Clipboard.GetImage(); //清除粘贴板 Clipboard.Clear(); //返回得到的验证码 return CodeImage; }
因为这段代码需要用到粘贴板,所以你在允许程序的时候,保证没有阻碍粘贴板运行的程序,不然会报“所请求的剪贴板操作失败”
3.如何判断webBroswer是否加载完毕
if (webBrowser1.ReadyState == WebBrowserReadyState.Complete) { }
4.如何让webbrowser在Navigate结束后,完成某个add函数
//Navigate结束事件 webBrowser1.Navigated += new WebBrowserNavigatedEventHandler(add);
5.如果在通过HtmlElement控制网页时,如果出现选择框如何处理
//用SetAttribute就可以 比如: <input type="button" id="btnShenshen" class="button" value="返 回" onclick="javascript:window.location.href='/jsxsd/pyfa/topyfamx';"/> 学年学期:<select name="xnxqh" id="xnxqh" style="width:180px;" onchange="initJc(this)"> <option value="2019-2020-2" >2019-2020-2</option> <option value="2019-2020-1" >2019-2020-1</option> <option value="2018-2019-2" >2018-2019-2</option> </select> HtmlElement btnShenshen = webBrowser.Document.All["btnShenshen"]; //让他选择2019-2020-2 btnShenshen.SetAttribute("value","2019-2020-2");
6.如果在通过HtmlElement控制网页时,如果出现按钮如何处理
//有一个按钮,但是其源代码是 <input type="button" value="查 询" class="button" onclick="search(this)"/> //我无法找到他的id 或者是 name //最终才发现,这直接是调用一个函数,search(this) //查阅资料后,可以通过这样的方式,直接调用js函数 webBrowser1.Navigate("javascript:search(this);");
//如果知道他的id,可以用另一种更直观的方法调用他的函数 //onclick 为js函数 HtmlElement_t.RaiseEvent("onclick"); //但是如果不知道id,就不行了
7.如果给pictureBox1设置一个单击事件,事件内容是,网页的验证码点击一次(更换),然后再通过上面写的GetCodeImg函数更新pictureBox1的图片,发现总是延后,无法正确显示验证码,用Thread.sleep(1000);也无法解决问题。
8.如何用webBrowser执行网页中的js函数
//js函数定义 function search(obj){ //判断是否选了周次并比较大小 var zc1 = $("#zc1").val(); var zc2 = $("#zc2").val(); if(zc1!=""&&zc2!=""){ zc1 = parseInt(zc1); zc2 = parseInt(zc2); if(zc1>zc2){ alert("开始周次不能大于结束周次!"); return false; } } var jc1 = $("#jc1").val(); var jc2 = $("#jc2").val(); if(jc1!="" && jc2!=""){ if(parseInt(jc1) > parseInt(jc2)){ alert("开始节次不能大于结束节次!"); return false; } } document.getElementById('Form1').submit(); }
//js函数调用的地方 <input type="button" value="查 询" class="button" onclick="search(this)">
第一种
webBrowser1.Navigate("javascript:search(this);");
第二种
webBrowser1.Document.InvokeScript("search",new object[] { "this"});
9.如何读取iframe里的内容
<iframe id="fcenter" name="fcenter" style="height:100%; VISIBILITY: inherit; WIDTH: 100%"></iframe>
//需要使用 webBrowser1.Document.Window.Frames["fcenter"].Document.All["***"].InnerHtml;
//***为标签内部的控件id
10.如何读取数据库查询的结果
cmd.CommandText = "select name,teacher,room,time,id,week from course where class like N'"+ CurrentNode.Text + "'"; SqlDataAdapter ada = new SqlDataAdapter(cmd.CommandText, conn); DataTable dt = new DataTable(); ada.Fill(dt); foreach (var t in dt.Rows){}
Happy Ending!~