實現此功能首先需要借助一些抓包工具,對相應的網站登陸過程進行分析,此過程根據網站的不同,可能復雜,也可能很簡單。常用的抓包工具FF下FireBug和IE下的HttpWatch.這兩個工具很強大,以此工具獲取的信息足以應對C#模擬網站登陸過程所需要的信息。抓包工具的使用教程網上很多,例如FireBug教程,在此就不做過多介紹。當然網上C# C/S結構模擬網站登陸信息也很多,但基本都是代碼片段或是邏輯很復雜。所以把我實踐的過程寫下來與大家分享。此實驗過程是基於模擬登陸校內而完成的。
首先使用FireBug 獲取登陸相關信息,在點登陸之前先把FireBug中信息清除,這樣獲取的信息就從點擊登陸按鈕后開始,以便后續分析,如下圖:
每次請求與下一次請求之間的聯系就是每次請求后返回的Cookies數據,前一次的返回Cookie數據需要同下一次請求一同發送到服務器,這也是C#模擬網站登陸的關鍵。詳見以下邏輯代碼:

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代碼的邏輯。

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數據,只要這步原理理解,此過程也就沒有什么難度了。