c# webbrowser的几个问题:自动点击确定安全证书、判断页面加载完成、提取网页字符串

jay314159 2010-01-27 11:26:40
我想提取某个网站的一个子页面的一个字符串,是IP地址来的。
但是访问那个网站要先登录。
网站是局域网,外网无法访问,抱歉。
所以我先做了一个自动填表的小程序。
现在遇到几个问题如下:

1.自动点击确定安全证书
使用webBrowser.Navigate定位到网站时会弹出安全证书,上面有三个按钮“是”“否”“详细信息”,我想让它自动点击“是”应该怎么做呢?
点击“登陆”后还会弹出一个“安全信息”对话框,也有上面三个按钮,想让它自动点击“是”,这样才能成功登陆。

2.判断页面加载完成
一般情况下可以用webBrowser1_DocumentCompleted方法,但是我发现程序只在定位到第一个URL时调用webBrowser1_DocumentCompleted,如果我登陆后想webBrowser.Navigate跳转到另一个子页面,就没有调用webBrowser1_DocumentCompleted了。然后读取网页文档内容就会出现空对象的问题。
我的代码如下:

public partial class Form1 : Form
{
bool isload = false;
public Form1()
{
InitializeComponent();
webBrowser1.Navigate(url1);//第一个页面
}
private void Form1_Load(object sender, EventArgs e)
{
}

private void button1_Click_1(object sender, EventArgs e)
{
HtmlElement element = webBrowser1.Document.GetElementById("username");
element.InnerText = "07lls";
element = webBrowser1.Document.GetElementById("password");
element.InnerText = "1";
webBrowser1.Document.GetElementById("image").InvokeMember("Click");

//this.webBrowser1_DocumentCompleted(null ,null);
if (isload)
{
isload = false;
webBrowser1.Navigate(url2);//跳到第二个页面
}
//this.webBrowser1_DocumentCompleted(null, null);
if (isload )
{
isload = false;
HtmlElement temp = webBrowser1.Document.GetElementById("LogonHistory1_dgResult");
//System.Threading.Thread.Sleep(10000);
MessageBox.Show(temp.ToString());
}
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
isload = true;
}
}
}



3.如何提取网页的内容
第二个页面的源文件如下:
==============================================
<FONT face="宋体">
<table cellspacing="0" rules="all" border="1" id="LogonHistory1_dgResult" style="border-width:1px;border-style:solid;font-size:X-Small;width:100%;border-collapse:collapse;">
<tr class="tableTag" nowrap="nowrap" align="Center">
<td nowrap="nowrap"><a href="javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl0','')">登录IP</a></td><td nowrap="nowrap"><a href="javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl1','')">登录时间</a></td><td nowrap="nowrap"><a href="javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl2','')">登出时间</a></td><td nowrap="nowrap"><a href="javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl4','')">在线时间</a></td><td nowrap="nowrap"><a href="javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl5','')">国内流量</a></td><td nowrap="nowrap"><a href="javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl6','')">国际流量</a></td>
</tr><tr nowrap="nowrap" align="Center" style="background-color:White;height:25px;">
<td>10.18.2.10</td><td nowrap="nowrap" align="Left">2010-1-27 9:15:32</td><td nowrap="nowrap" align="Left"> </td><td nowrap="nowrap" align="Right">0:12'36"</td><td nowrap="nowrap" align="Right">0.02 M </td><td nowrap="nowrap" align="Right">0 M </td>
</tr><tr nowrap="nowrap" align="Center" style="background-color:#F7F7F7;height:25px;">
<td>10.18.2.10</td><td nowrap="nowrap" align="Left">2010-1-27 8:49:26</td><td nowrap="nowrap" align="Left">2010-1-27 9:14:35</td><td nowrap="nowrap" align="Right">0:25'09"</td><td nowrap="nowrap" align="Right">4 M </td><td nowrap="nowrap" align="Right">0 M </td>
</tr><tr nowrap="nowrap" align="Center" style="background-color:White;height:25px;">
<td>10.184.2.10</td><td nowrap="nowrap" align="Left">2010-1-26 18:45:34</td><td nowrap="nowrap" align="Left">2010-1-26 23:40:51</td><td nowrap="nowrap" align="Right">4:55'17"</td><td nowrap="nowrap" align="Right">40.92 M </td><td nowrap="nowrap" align="Right">0 M </td>
......
==============================================

如果我想找出第一个IP地址,上面是第一个“10.18.2.10”,应该怎么做呢?
如果用webBrowser.Document.GetElementById("");引号内应该填什么元素名?

问题较多,分数较少,请见谅!
谢谢回答!
...全文
1261 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
hanqiangfei 2012-02-15
  • 打赏
  • 举报
回复
呵呵,不错, 支持下
hbhdyn 2010-01-28
  • 打赏
  • 举报
回复
最近,我也在研究;
网上搜索到很多的,可以自动确定;不知道是否适合你;
jay314159 2010-01-28
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 jasper 的回复:]
这个问题比较复杂
核心:可以利用win32 API函数实现,导入User32.dll。
思路:启动timer,获取窗体,操作鼠标模拟点击事件,关闭timer
[/Quote]

试试看
谢谢
jasper 2010-01-28
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 jay314159 的回复:]
引用 9 楼 qlzf11140820 的回复:
引用 8 楼 jay314159 的回复:
...
很好,谢谢!迟点给分。
等等看看第一个问题是否有人能解决。
[/Quote]
这个问题比较复杂
核心:可以利用win32 API函数实现,导入User32.dll。
思路:启动timer,获取窗体,操作鼠标模拟点击事件,关闭timer
参考代码:

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll ")]
public static extern System.IntPtr FindWindowEx(System.IntPtr parent, System.IntPtr childe, string strclass, string strname);
[DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam);
[DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
private static extern void SetForegroundWindow(IntPtr hwnd);


const uint BM_CLICK = 0xF5;

//取得消息框的句柄
IntPtr p = FindWindowEx(System.IntPtr.Zero, System.IntPtr.Zero, null, "Choose a digital certificate");

//取得OK按钮的句柄
IntPtr hwndok = FindWindowEx(p, System.IntPtr.Zero, null, "Ok");

//显示到前端
SetForegroundWindow(p);

//模拟点击按钮
SendMessage(hwndok, BM_CLICK, 0, 0);

this.Close();
qlzf11140820 2010-01-27
  • 打赏
  • 举报
回复
2:.........

private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (webBrowser1.ReadyState == WebBrowserReadyState.Complete)
{
//完成
}
}
lvxianda 2010-01-27
  • 打赏
  • 举报
回复
up
jay314159 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 qlzf11140820 的回复:]
IE -- 工具--internet选项--安全--自定义级别----其他---加载应用程序 和不安全文件 --选 启动

试试
[/Quote]
还是会弹出。
而且如果给别人用的话,
不能让用户都设置成 “启动”啊
qlzf11140820 2010-01-27
  • 打赏
  • 举报
回复
IE -- 工具--internet选项--安全--自定义级别----其他---加载应用程序 和不安全文件 --选 启动

试试
jay314159 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 qlzf11140820 的回复:]
弹出一个“安全信息”对话框
-------
弹出的对话框在webBrowser中 还是类似win.open()
能不能不要弹出?
[/Quote]

访问那个网站的时候,先会弹出“安全证书”对话框,点击“是”后会接着弹出一个“安全信息”对话框,再点击“是”后才能访问到登陆界面。
应该是在webbrowser弹出的。(==!汗,我不知道什么是win.open())
不知道能否不要弹出,因为即使在浏览器打开那个网站也会弹出安全证书。
qlzf11140820 2010-01-27
  • 打赏
  • 举报
回复
弹出一个“安全信息”对话框
-------
弹出的对话框在webBrowser中 还是类似win.open()
能不能不要弹出?
jay314159 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 qlzf11140820 的回复:]
引用 8 楼 jay314159 的回复:
读取整个网页文档

用正则也可以的
C# codestring Html="<FONT face=\"宋体\"> <table cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"LogonHistory1_dgResult\" style=\"border-width:1px;border-style:solid;font-size:X-Small;width:100%;border-collapse:collapse;\"> <tr class=\"tableTag\" nowrap=\nowrap\" align=\"Center\"> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl0','')\">登录IP </a> </td> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl1','')\">登录时间 </a> </td> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl2','')\">登出时间 </a> </td> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl4','')\">在线时间 </a> </td> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl5','')\">国内流量 </a> </td> <td nowrap=\nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl6','')\">国际流量 </a> </td> </tr> <tr nowrap=\"nowrap\" align=\"Center\" style=\"background-color:White;height:25px;\"> <td>10.18.2.10 </td> <td nowrap=\"nowrap\" align=\"Left\">2010-1-27 9:15:32 </td> <td nowrap=\"nowrap";
Regex r=new Regex(@"(?is)(?<=<td>)(?:(?!</?/td\b).)*(?=</td>)", RegexOptions.Compiled| RegexOptions.IgnoreCase);foreach (Match min r.Matches(Html))
{foreach(Capture cin m.Captures)
{string IP= c.Value;
}
}
[/Quote]

很好,谢谢!迟点给分。
等等看看第一个问题是否有人能解决。
qlzf11140820 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 jay314159 的回复:]
引用 7 楼 qlzf11140820 的回复:
C# codestring Html=" <FONT face=\"宋体\"> <table cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"LogonHistory1_dgResult\" style=\"border-width:1px;border-style:solid;font-size:X-Small;width:100%;border?-


呃……
我上面那部分网页源文件是那个页面的全部源文件的一部分,
那个源文件是要通过程序自动读出来的,
然后让程序返回那个IP,
那么,我应该用什么webbrowser的语句把 <td> 和 之后的第一个 </td>之间的东西取出来?
webBrowser.Document.All("");应该是读取整个网页文档吧?

[/Quote]读取整个网页文档

用正则也可以的
 string Html = "<FONT face=\"宋体\"> <table cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"LogonHistory1_dgResult\" style=\"border-width:1px;border-style:solid;font-size:X-Small;width:100%;border-collapse:collapse;\"> <tr class=\"tableTag\" nowrap=\nowrap\" align=\"Center\"> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl0','')\">登录IP </a> </td> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl1','')\">登录时间 </a> </td> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl2','')\">登出时间 </a> </td> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl4','')\">在线时间 </a> </td> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl5','')\">国内流量 </a> </td> <td nowrap=\nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl6','')\">国际流量 </a> </td> </tr> <tr nowrap=\"nowrap\" align=\"Center\" style=\"background-color:White;height:25px;\"> <td>10.18.2.10 </td> <td nowrap=\"nowrap\" align=\"Left\">2010-1-27 9:15:32 </td> <td nowrap=\"nowrap";
Regex r = new Regex(@"(?is)(?<=<td>)(?:(?!</?/td\b).)*(?=</td>)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
foreach (Match m in r.Matches(Html))
{
foreach(Capture c in m.Captures)
{
string IP = c.Value;
}
}
jay314159 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 qlzf11140820 的回复:]
C# codestring Html="<FONT face=\"宋体\"> <table cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"LogonHistory1_dgResult\" style=\"border-width:1px;border-style:solid;font-size:X-Small;width:100%;border?-
[/Quote]

呃……
我上面那部分网页源文件是那个页面的全部源文件的一部分,
那个源文件是要通过程序自动读出来的,
然后让程序返回那个IP,
那么,我应该用什么webbrowser的语句把<td> 和 之后的第一个 </td>之间的东西取出来?
webBrowser.Document.All("");应该是读取整个网页文档吧?
qlzf11140820 2010-01-27
  • 打赏
  • 举报
回复
  string Html = "<FONT face=\"宋体\"> <table cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"LogonHistory1_dgResult\" style=\"border-width:1px;border-style:solid;font-size:X-Small;width:100%;border-collapse:collapse;\"> <tr class=\"tableTag\" nowrap=\nowrap\" align=\"Center\"> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl0','')\">登录IP </a> </td> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl1','')\">登录时间 </a> </td> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl2','')\">登出时间 </a> </td> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl4','')\">在线时间 </a> </td> <td nowrap=\"nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl5','')\">国内流量 </a> </td> <td nowrap=\nowrap\"> <a href=\"javascript:__doPostBack('LogonHistory1$dgResult$_ctl2$_ctl6','')\">国际流量 </a> </td> </tr> <tr nowrap=\"nowrap\" align=\"Center\" style=\"background-color:White;height:25px;\"> <td>10.18.2.10 </td> <td nowrap=\"nowrap\" align=\"Left\">2010-1-27 9:15:32 </td> <td nowrap=\"nowrap";
int count = Html.Length;
int starIndex = Html.IndexOf("<td>", 0, count);
int endIndex = Html.IndexOf("</td>", starIndex, count - starIndex);
string IP = Html.Substring(starIndex+4, endIndex - starIndex-4);
qlzf11140820 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 jay314159 的回复:]
引用 4 楼 jasper 的回复:
这个问题的难点就在于10.18.2.10 两边没有可区别的tag
且10.18.2.10 这个字符串也不好判断

可以考虑将页面中所有 <td> </td>之间的字符串取出,放入一个数组,
然后遍历数组,将每一个按 “.” split一下,判断aplit后的是否长度是4,并且全是 <=3位的数字。
这中情况下出错的概率应该可以忽略不计了。


这方法似乎行得通
那么我应该用什么语句把所有的 <td> </td>之间的字符串取出来呢?谢谢
[/Quote]取第一个<td> 和 之后的第一个</td>之间的就好了,截取或者正则
jay314159 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jasper 的回复:]
这个问题的难点就在于10.18.2.10 两边没有可区别的tag
且10.18.2.10 这个字符串也不好判断

可以考虑将页面中所有 <td> </td>之间的字符串取出,放入一个数组,
然后遍历数组,将每一个按 “.” split一下,判断aplit后的是否长度是4,并且全是 <=3位的数字。
这中情况下出错的概率应该可以忽略不计了。
[/Quote]

这方法似乎行得通
那么我应该用什么语句把所有的<td> </td>之间的字符串取出来呢?谢谢
jasper 2010-01-27
  • 打赏
  • 举报
回复
这个问题的难点就在于10.18.2.10 两边没有可区别的tag
且10.18.2.10 这个字符串也不好判断

可以考虑将页面中所有<td></td>之间的字符串取出,放入一个数组,
然后遍历数组,将每一个按 “.” split一下,判断aplit后的是否长度是4,并且全是<=3位的数字。
这中情况下出错的概率应该可以忽略不计了。
jay314159 2010-01-27
  • 打赏
  • 举报
回复
谢谢楼上^_^
希望更多的回答
不要让我那么失望啊
每次100分的帖都很少人理
低分的就更不用说了
再说,我最多只能开100分啊

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧