操纵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();
}
}
}