C# 模拟网站登陆

       实现此功能首先需要借助一些抓包工具,对相应的网站登陆过程进行分析,此过程根据网站的不同,可能复杂,也可能很简单。常用的抓包工具FF下FireBug和IE下的HttpWatch.这两个工具很强大,以此工具获取的信息足以应对C#模拟网站登陆过程所需要的信息。抓包工具的使用教程网上很多,例如FireBug教程,在此就不做过多介绍。当然网上C# C/S结构模拟网站登陆信息也很多,但基本都是代码片段或是逻辑很复杂。所以把我实践的过程写下来与大家分享。此实验过程是基于模拟登陆校内而完成的。

首先使用FireBug 获取登陆相关信息,在点登陆之前先把FireBug中信息清除,这样获取的信息就从点击登陆按钮后开始,以便后续分析,如下图:

每次请求与下一次请求之间的联系就是每次请求后返回的Cookies数据,前一次的返回Cookie数据需要同下一次请求一同发送到服务器,这也是C#模拟网站登陆的关键。详见以下逻辑代码:

View Code
  1 using System;
  2 using System.Collections.Generic;
  3 using System.IO;
  4 using System.Linq;
  5 using System.Net;
  6 using System.Text;
  7 using System.Threading.Tasks;
  8 using System.Windows.Forms;
  9 
 10 namespace WebHelp
 11 {
 12     public class WebAutoLogin
 13     {
 14         #region 属性
 15         /// <summary>
 16         /// 登陆后返回的Html
 17         /// </summary>
 18         public static string ResultHtml
 19         {
 20             get;
 21             set;
 22         }
 23         /// <summary>
 24         /// 下一次请求的Url
 25         /// </summary>
 26         public static string NextRequestUrl
 27         {
 28             get;
 29             set;
 30         }
 31         /// <summary>
 32         /// 若要从远程调用中获取COOKIE一定要为request设定一个CookieContainer用来装载返回的cookies
 33         /// </summary>
 34         public static CookieContainer CookieContainer
 35         {
 36             get;
 37             set;
 38         }
 39         /// <summary>
 40         /// Cookies 字符创
 41         /// </summary>
 42         public static string CookiesString
 43         {
 44             get;
 45             set;
 46         }
 47         #endregion
 48 
 49         #region 方法
 50         /// <summary>
 51         /// 用户登陆指定的网站
 52         /// </summary>
 53         /// <param name="loginUrl"></param>
 54         /// <param name="account"></param>
 55         /// <param name="password"></param>
 56         public static void PostLogin(string loginUrl, string account, string password)
 57         {
 58             HttpWebRequest request = null;
 59             HttpWebResponse response = null;
 60             try
 61             {
 62                 string postdata = "email=" + account + "&password="+password+"&origURL=" + "http://www.renren.com/home" + "&domain=renren.com";//模拟请求数据,数据样式可以用FireBug插件得到。
 63                // string LoginUrl = "http://www.renren.com/PLogin.do";
 64                 request = (HttpWebRequest)WebRequest.Create(loginUrl);//实例化web访问类  
 65                 request.Credentials = CredentialCache.DefaultCredentials;
 66                 request.Method = "POST";//数据提交方式为POST  
 67                 request.ContentType = "application/x-www-form-urlencoded";    //模拟头  
 68                 request.AllowAutoRedirect = false;   // 不用需自动跳转
 69                 //必须设置CookieContainer存储请求返回的Cookies
 70                 if (CookieContainer != null)
 71                 {
 72                     request.CookieContainer = CookieContainer;
 73                 }
 74                 else
 75                 {
 76                     request.CookieContainer = new CookieContainer();
 77                     CookieContainer = request.CookieContainer;
 78                 }
 79                 request.KeepAlive = true;
 80                 //提交请求  
 81                 byte[] postdatabytes = Encoding.UTF8.GetBytes(postdata);
 82                 request.ContentLength = postdatabytes.Length;
 83                 Stream stream;
 84                 stream = request.GetRequestStream();
 85                 //设置POST 数据
 86                 stream.Write(postdatabytes, 0, postdatabytes.Length);
 87                 stream.Close();
 88                 //接收响应  
 89                 response = (HttpWebResponse)request.GetResponse();
 90                 //保存返回cookie  
 91                 response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
 92                 CookieCollection cook = response.Cookies;
 93                 string strcrook = request.CookieContainer.GetCookieHeader(request.RequestUri);
 94                 CookiesString = strcrook;
 95                 //取下一次GET跳转地址  
 96                 StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
 97                 string content = sr.ReadToEnd();
 98                 sr.Close();
 99                 request.Abort();
100                 response.Close();
101                 //依据登陆成功后返回的Page信息,求出下次请求的url
102                 //每个网站登陆后加载的Url和顺序不尽相同,以下两步需根据实际情况做特殊处理,从而得到下次请求的URL
103                 string[] substr = content.Split(new char[] { '"' });
104                 NextRequestUrl = substr[1];
105             }
106             catch (WebException ex)
107             {
108                 MessageBox.Show(string.Format("登陆时出错,详细信息:{0}", ex.Message));
109             }
110         }
111         /// <summary>
112         /// 获取用户登陆后下一次请求返回的内容
113         /// </summary>
114         public static void GetPage()
115         {
116             HttpWebRequest request = null;
117             HttpWebResponse response = null;
118             try
119             {
120                 request = (HttpWebRequest)WebRequest.Create(NextRequestUrl);
121                 request.Credentials = CredentialCache.DefaultCredentials;
122                 request.Method = "GET";
123                 request.KeepAlive = true;
124                 request.Headers.Add("Cookie:" + CookiesString);
125                 request.CookieContainer = CookieContainer;
126                 request.AllowAutoRedirect = false;
127                 response = (HttpWebResponse)request.GetResponse();
128                 //设置cookie  
129                 CookiesString = request.CookieContainer.GetCookieHeader(request.RequestUri);
130                 //取再次跳转链接  
131                 StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
132                 string ss = sr.ReadToEnd();
133                 sr.Close();
134                 request.Abort();
135                 response.Close();
136                 //依据登陆成功后返回的Page信息,求出下次请求的url
137                 //每个网站登陆后加载的Url和顺序不尽相同,以下两步需根据实际情况做特殊处理,从而得到下次请求的URL
138                 string[] substr = ss.Split(new char[] { '"' });
139                 NextRequestUrl = substr[1];
140                 ResultHtml = ss;
141             }
142             catch (WebException ex)
143             {
144                 MessageBox.Show(string.Format("获取页面HTML信息出错,详细信息:{0}",ex.Message));
145             }
146         }
147         #endregion
148 
149     }
150 }

以下是测试代码,POST请求一次,GET请求三次。最后得到登陆后加载的首页的HTML代码。当然,登陆后就可以依据当前的Cookie数据获取网站的其他子页面HTML。以下是登陆后加载的首页的HTML代码的逻辑。

View Code
1   private void Form1_Load(object sender, EventArgs e)
2         {
3             WebAutoLogin.PostLogin("http://www.renren.com/PLogin.do", "niuwenwen668@sina.com", "xxxxxxx");
4             WebAutoLogin.GetPage();
5             WebAutoLogin.GetPage();
6             WebAutoLogin.GetPage();
7             webBrowser1.DocumentText = WebAutoLogin.ResultHtml;
8         }

第一次POST数据的URL为登陆提交数据的页面,此地址不一定能在抓包工具中得到,这就需要分析,方法很多(网上很多),例如查看登陆页面源码等。


  POST提交的数据可以在抓包工具中得到,以下是FireBug中得到的信息:

把代码Copy执行以下,自动登录成功了吧!!

好了,就这些了,此过程中就是每次请求都延续应用前一次请求返回的Cookie数据,只要这步原理理解,此过程也就没有什么难度了。

posted @ 2013-04-09 15:59  行与止  阅读(4808)  评论(1编辑  收藏  举报