操纵IE浏览器模拟用户登录网站

[转自:amandag的专栏]

大多数C#程序员对于使用HttpRequest、HttpResponse、WebClient这样的类向Web服务器发出请求并取得响应结果并不陌生。

但有时我们想模拟用户操纵浏览器的场景(尤其是在自动化测试时),那么我们可以选择使用mshtml.dll和shdocvw.dll来完成对IE DOM的操作以实现此功能。

假设我们想访问http://community.csdn.net/,并在这之前已经登录,那么实际上我们应该访问http://passport.csdn.net/UserLogin.aspx?from=http://community.csdn.net/,并在此页面输入用户名、密码、验证码并点击登录按钮。

首先我们新建一个Console项目,并添加对mshtml.dll(添加引用--.NET选项卡--Microsoft.mshtml)和shdocvw.dll(添加引用--COM选项卡--Microsoft Internet Controls)的引用。

详细内容请参考代码注释

[c-sharp] view plaincopyprint?

using System;

using System.Diagnostics;

using System.Threading;

using mshtml;

using SHDocVw;

 

namespace IEDemo

{

class Program

{

static AutoResetEvent documentComplete = new AutoResetEvent(false);

 

static void Main(string[] args)

{

Console.WriteLine(DateTime.Now.ToString() + " 开始");

InternetExplorer ie = GetInternetExplorer();

if (ie != null)

{

Run(ie);

}

Console.WriteLine(DateTime.Now.ToString() + " 结束");

}

 

private static InternetExplorer GetInternetExplorer()

{

InternetExplorer ie = null;

Console.WriteLine(DateTime.Now.ToString() + " 加载IE实例");

 

//查找是否有打开的IE进程窗口,如果已经包含CSDN登录页,则得到此进程

Process[] processes = Process.GetProcesses();

Process process = null;

foreach (Process p in processes)

{

if (string.Compare(p.ProcessName, "iexplore", true) == 0)

{

if (p.MainWindowTitle.IndexOf("CSDN 用户登录") >= 0) // CSDN 用户登录 - Windows Internet Explorer

 

{

process = p;

break;

}

}

}

 

//如果没有则启动IE实例

if (process == null)

{

process = Process.Start("iexplore.exe", "about:blank");

}

 

if (process == null)

{

Console.WriteLine(DateTime.Now.ToString() + " 无法启动IE");

return null;

}

 

Thread.Sleep(3000);

try

{

 

Console.WriteLine(DateTime.Now.ToString() + " Process Handle: " + process.MainWindowHandle.ToString());

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

return null;

}

 

ShellWindows browsers = new ShellWindows();

Console.WriteLine(DateTime.Now.ToString() + " 活动浏览器数量: " + browsers.Count);

if (browsers.Count == 0)

{

Console.WriteLine(DateTime.Now.ToString() + " 未找到IE");

}

 

//如果找到匹配的IE进程,则把当前InternetExplorer对象连接到正在运行的IE程序

Console.WriteLine(DateTime.Now.ToString() + " 附加到IE");

int i = 0;

while (i < browsers.Count && ie == null)

{

InternetExplorer e = browsers.Item(i) as InternetExplorer;

if (e != null)

{

if (e.HWND == (int)process.MainWindowHandle)

{

ie = e;

break;

}

}

++i;

}

if (ie == null)

{

Console.WriteLine(DateTime.Now.ToString() + " 附加到IE失败");

}

return ie;

}

 

private static void Run(InternetExplorer ie)

{

ie.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(ie_DocumentComplete);

 

try

{

HTMLDocument document = null;

 

object o = new object();

//导航到CSDN登录页

ie.Navigate("http://passport.csdn.net/UserLogin.aspx?from=http://community.csdn.net/", ref o, ref o, ref o, ref o);

documentComplete.WaitOne(1000, true);

 

document = ie.Document as HTMLDocument;

if (document != null)

{

//以下操纵IE Shell

HTMLInputButtonElement name = document.getElementById("ctl00_CPH_Content_tb_LoginNameOrLoginEmail") as HTMLInputButtonElement;

if (name != null)

{

//csdn用户名

name.value = "yourcsdnusername";

}

HTMLInputButtonElement password = document.getElementById("ctl00_CPH_Content_tb_Password") as HTMLInputButtonElement;

if (password != null)

{

//csdn密码

password.value = "yourcsdnpassword";

}

 

HTMLInputButtonElement imagecode = document.getElementById("ctl00_CPH_Content_tb_ExPwd") as HTMLInputButtonElement;

if (imagecode != null)

{

Console.Write("输入验证码:");

//控制台窗口输入验证码

string code = Console.ReadLine();

imagecode.value = code;

}

 

HTMLInputButtonElement submit = document.getElementById("ctl00_CPH_Content_Image_Login") as HTMLInputButtonElement;

if (submit != null)

{

submit.click();

documentComplete.WaitOne(1000, true);

}

}

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

}

 

// ie.Quit();

}

 

private static void ie_DocumentComplete(object pDisp, ref object URL)

{

documentComplete.Set();

}

}

}

posted @ 2012-05-07 17:36  Luke Zhang  阅读(1304)  评论(0编辑  收藏  举报