剛學(xué)c#不久,也不太懂什么IHTMLDocument、IHTMLDocument2、IWebBrowser2等等。自己琢磨了好久,終于知道了怎么用WebBrowser操作frame和iframe。
1.獲取frame的源文件
MessageBox.Show(webBrowser1.Document.Window.Frames["main"].Document.Body.InnerHtml);
2.獲取frame的HTMLDocument接口
HTMLDocument doc =(HTMLDocument)webBrowser1.Document.DomDocument;
object j;
for (int i = 0; i < doc.parentWindow.frames.length; i++)
{
j = i;
HTMLWindow2Class frame = doc.parentWindow.frames.item(refj) as HTMLWindow2Class;
if (frame.name == "main")
{
MessageBox.Show(frame.document.title);
}
}
3.獲取frame的IHTMLDocument2接口
IHTMLDocument2 doc = (IHTMLDocument2)webBrowser1.Document.Window.Frames["main"].Document.DomDocument;
4.取得frame中被點(diǎn)擊的連接
private void webBrowser1_Navigating(objectsender, WebBrowserNavigatingEventArgs e)
{
string url =webBrowser1.Document.Window.Frames["main"].Document.ActiveElement.GetAttribute("src");
}
C# 通過(guò)webBrowser 框架網(wǎng)頁(yè)
首先對(duì)webBrowser加載網(wǎng)頁(yè)
this.webBrowser1.Url= new System.Uri("url地址", System.UriKind.Absolute);
給一般不是框架網(wǎng)頁(yè)中的文本框賦值
webBrowser1.Document.GetElementById("文本框ID").InnerText= "weiling";//文本框賦值根據(jù)ID賦值
this.webBrowser1.Document.All["文本框name"].SetAttribute("value", "0924");//文本框賦值根據(jù)name賦值
表單提交,也可以看成是一個(gè)點(diǎn)擊事件
HtmlElement form= webBrowser1.Document.GetElementById("formID");//提交表單
form.InvokeMember("submit");
框架網(wǎng)頁(yè)中的文本框賦值,"frameMain"是框架的name
webBrowser1.Document.Window.Frames["frameMain"].Document.GetElementById("txtXingming").InnerText= "521656";//框架賦值
注:frameMain 是框架的name
框架網(wǎng)頁(yè)中下拉框賦值
HtmlDocument doc= webBrowser1.Document.Window.Frames["frameMain"].Document;//框架下下拉框賦值
HtmlElement el= doc.GetElementById("drpXingbie");
el.SetAttribute("selectedIndex","1");
網(wǎng)頁(yè)控件沒(méi)有ID時(shí)的操作
//防止頁(yè)面多次刷新頁(yè)面執(zhí)行
if (num == 1)
{
string GetUserName =System.Configuration.ConfigurationSettings.AppSettings["Y2000UserName"].ToString();
string GetUserPassword =System.Configuration.ConfigurationSettings.AppSettings["Y2000UserPassword"].ToString();
int a = 1;
int all =webBrowser1.Document.Body.All.Count;
for (int i = 0; i < all;i++)
{
HtmlElementGetElement = webBrowser1.Document.All[i];
//取到包含input標(biāo)簽的元素
if(GetElement.TagName.ToUpper().ToString() == "INPUT")
{
//根據(jù)input的Name屬性,找到該元素并賦值:給用戶名輸入框賦值
if(GetElement.Name.ToString() == "UserName")
{
webBrowser1.Document.All[i].SetAttribute("value",GetUserName);
}
//根據(jù)input的Name屬性,找到該元素并賦值:給密碼輸入框賦值
if(GetElement.Name.ToString() == "Passwd")
{
webBrowser1.Document.All[i].SetAttribute("value",GetUserPassword);
}
}
//根據(jù)input的Name屬性,找到提交按鈕并執(zhí)行動(dòng)作
if(GetElement.Name.ToString() == "Submit")
{
//過(guò)濾點(diǎn)擊頁(yè)面中相同"name=Submit"的元素
if (a == 1)
{
webBrowser1.Document.All[i].InvokeMember("click");
}
a++;
}
}
num++;
}
C# WebBrowser實(shí)現(xiàn)網(wǎng)頁(yè)自動(dòng)填表
曾今向網(wǎng)友介紹過(guò)我的一個(gè)自己編寫的自動(dòng)填寫網(wǎng)頁(yè)表單的小程序,很多網(wǎng)友都覺(jué)得很實(shí)用,也許多會(huì)對(duì)這個(gè)程序的源碼很感興趣,這里我只是簡(jiǎn)介下程序中用到的主要代碼。最初我是通過(guò)下面這篇文章漸漸積累的相關(guān)知識(shí),再慢慢完善,現(xiàn)轉(zhuǎn)來(lái)同大家分享,共同學(xué)習(xí)。
話說(shuō)有了WebBrowser類,終于不用自己手動(dòng)封裝SHDocVw的AxWebBrowser這個(gè)ActiveX控件了。這個(gè)類如果僅僅作為一 個(gè)和IE一模一樣瀏覽器,那就太沒(méi)意思了(還不如直接用IE呢)。那么,無(wú)論我們是想做一個(gè)“定制版IE”,還是希望利用HTML來(lái)做用戶界面(指 WinApp而非WebApp。許多單機(jī)軟件,包括Windows的幫助支持中心,都是HTML做的),都少不了Windows Form和包含在WebBrowser中的Web頁(yè)面的交互。本文將通過(guò)幾個(gè)實(shí)際的例子,初步介紹一下WinForm和WebBrowser所包含的 Web頁(yè)面之間的交互。
下面的代碼假設(shè)你已經(jīng)建立了一個(gè)Windows Form,上面有一個(gè)WebBrowser名為“webBrowser”。
Study Case 1:用WinForm的Event Handler響應(yīng)Web頁(yè)面的事件
現(xiàn)在有這樣一個(gè)Windows Application,它的界面上只有一個(gè)WebBrowser,顯示一個(gè)本地的HTML文件作為界面。現(xiàn)在的問(wèn)題是,所有邏輯都可以放在HTML文件 里,唯獨(dú)“關(guān)閉”按鈕遇到了困難——通常,Web頁(yè)面是沒(méi)有辦法直接控制瀏覽器的,更不用說(shuō)結(jié)束這個(gè)WinForm程序了。
但是,在.Net 2.0當(dāng)中,“由Windows Form響應(yīng)Web頁(yè)面的事件”已經(jīng)成為了現(xiàn)實(shí)。
在.Net 2.0中,整個(gè)HTML文檔以及其包含的各個(gè)HTML元素,都和一個(gè)個(gè)HtmlDocument、HtmlElement之類的.Net對(duì)象對(duì)應(yīng)。因此只 要找到這個(gè)“關(guān)閉”按鈕對(duì)應(yīng)的HtmlElement對(duì)象,為其click事件添加Event Handler即可。
假設(shè)HTML源代碼如下:
<html>
<body>
<input type="button" id="btnClose" value="關(guān)閉" />
body>
html>
那么找出該按鈕并為之添加Event Handler的代碼如下:
HtmlDocument htmlDoc = webBrowser.Document;
HtmlElement btnElement = htmlDoc.All["btnClose"];
if (btnElement != null)
{
btnElement.click += new HtmlElementEventHandler(HtmlBtnClose_Click);
}
其中HtmlBtnClose_Click是按下Web按鈕時(shí)的Event Handler。
很簡(jiǎn)單吧?那么稍稍高級(jí)一點(diǎn)的——我們都知道一個(gè)HTML元素可能有很多各種各樣的事件,而HtmlElement這個(gè)類只給出最常用、共通的幾 個(gè)。那么,如何響應(yīng)其他事件呢?這也很簡(jiǎn)單,只需要調(diào)用HtmlElement的AttachEventHandler就可以了:
btnElement.AttachEventHandler("onclick", new EventHandler(HtmlBtnClose_Click));
//這一句等價(jià)于上面的btnElement.click += new HtmlElementEventHandler(HtmlBtnClose_Click);
對(duì)于其他事件,把"onclick"換成該事件的名字就可以了。例如:
formElement.AttachEventHandler("onsubmit", new EventHandler(HtmlForm_Submit));
Study Case 2:表單(form)的自動(dòng)填寫和提交
要使我們的WebBrowser具有自動(dòng)填表、甚至自動(dòng)提交的功能,并不困難。
假設(shè)有一個(gè)最簡(jiǎn)單的登錄頁(yè)面,輸入用戶名密碼,點(diǎn)“登錄”按鈕即可登錄。已知用戶名輸入框的id(或Name,下同)是username,密碼輸入 框的id是password,“登錄”按鈕的id是submitbutton,那么我們只需要在webBrowser的 DocumentCompleted事件中使用下面的代碼即可:
HtmlElement btnSubmit = webBrowser.Document.All["submitbutton"];
HtmlElement tbUserid = webBrowser.Document.All["username"];
HtmlElement tbPasswd = webBrowser.Document.All["password"];
if (tbUserid == null ││ tbPasswd == null ││ btnSubmit == null)
return;
tbUserid.SetAttribute("value", "smalldust");
tbPasswd.SetAttribute("value", "12345678");
btnSubmit.InvokeMember("click");
這里我們用SetAttribute來(lái)設(shè)置文本框的“value”屬性,用InvokeMember來(lái)調(diào)用了按鈕的“click”方法。因?yàn)椴煌?Html元素,其擁有的屬性和方法也不盡相同,所以.Net 2.0提供了統(tǒng)一的HtmlElement來(lái)概括各種Html元素的同時(shí),提供了這兩個(gè)方法以調(diào)用元素特有的功能。關(guān)于各種Html元素的屬性和方法一 覽,可以查閱MSDN的。
※關(guān)于表單的提交,的確還有另一種方法就是獲取form元素而不是button,并用form元素的submit方法:
HtmlElement formLogin = webBrowser.Document.Forms["loginForm"];
//……
formLogin.InvokeMember("submit");
本文之所以沒(méi)有推薦這種方法,是因?yàn)楝F(xiàn)在的網(wǎng)頁(yè),很多都在submit按鈕上添加onclick事件,以對(duì)提交的內(nèi)容做最基本的驗(yàn)證。如果直接使用form的submit方法,這些驗(yàn)證代碼就得不到執(zhí)行,有可能會(huì)引起錯(cuò)誤。
Study Case 3:查找并選擇文本
這次我們希望實(shí)現(xiàn)一個(gè)和IE一模一樣的查找功能,以對(duì)Web頁(yè)面內(nèi)的文字進(jìn)行查找。
文本查找要借助于TextRange對(duì)象的findText方法。但是,.Net里并沒(méi)有這個(gè)對(duì)象。這是因?yàn)椋?Net 2.0提供的HtmlDocument,HtmlWindow,HtmlElement等類,只不過(guò)是對(duì)原有mshtml這個(gè)COM組件的不完整封裝,只 提供了mshtml的部分功能。所以許多時(shí)候,我們?nèi)耘f要借助mshtml來(lái)實(shí)現(xiàn)我們需要的功能。好在這些.Net類都提供了DomDocument這個(gè) 屬性,使得我們很容易把.Net對(duì)象轉(zhuǎn)換為COM對(duì)象使用。下面的代碼演示了如何查找Web頁(yè)面的文本。
(需要添加mshtml的引用,并加上using mshtml;)
public partial class SearchDemo : Form
{
// 建立一個(gè)查找用的TextRange(IHTMLTxtRange接口)
private IHTMLTxtRange searchRange = null;
public SearchDemo()
{
InitializeComponent();
}
private void btnSearch_Click(object sender, EventArgs e)
{
// Document的DomDocument屬性,就是該對(duì)象內(nèi)部的COM對(duì)象。
IHTMLDocument2 document = (IHTMLDocument2)webBrowser.Document.DomDocument;
string keyword = txtKeyword.Text.Trim();
if (keyword == "")
return;
// IE的查找邏輯就是,如果有選區(qū),就從當(dāng)前選區(qū)開頭+1字符處開始查找;沒(méi)有的話就從頁(yè)面最初開始查找。
// 這個(gè)邏輯其實(shí)是有點(diǎn)不大恰當(dāng)?shù)?,我們這里不用管,和IE一致即可。
if (document.selection.type.ToLower() != "none")
{
searchRange = (IHTMLTxtRange)document.selection.createRange();
searchRange.collapse(true);
searchRange.moveStart("character", 1);
}
else
{
IHTMLBodyElement body = (IHTMLBodyElement)document.body;
searchRange = (IHTMLTxtRange)body.createTextRange();
}
// 如果找到了,就選?。ǜ吡溜@示)該關(guān)鍵字;否則彈出消息。
if (searchRange.findText(keyword, 1, 0))
{
searchRange.select();
}
else
{
MessageBox.Show("已搜索到文檔結(jié)尾。");
}
}
}
到此為止,簡(jiǎn)單的查找就搞定了。至于替換功能,看了下一個(gè)例子,我相信你就可以觸類旁通輕松搞定了
該文章在 2017/2/16 16:36:47 編輯過(guò)