使用C#的HttpWebRequest模擬登陸訪問人人網


無論使用任何語言做模擬登陸或者抓取訪問頁面,無外乎以下思路:
第一 啟用一個web訪問會話方法或者實例化一個web訪問類,如.net中的HttpWebRequest;
第二 模擬POST或者GET方式提交的數據;
第三 模擬請求的頭;
第四 提交請求並獲得響應,及對響應做我們所需要的處理。
這里我們以人人網的登錄為例,將涉及到POST以及GET兩種請求方式。
在之前的文章《免費網頁抓包工具,火狐插件FireBug的抓包使用教程》中我們知道,登陸人人網的時候,一共做了一個POST請求以及兩個GET請求,如下圖:

人人網登錄請求

觀察這三個請求的詳細信息,不難看出第一個GET請求的地址可以由POST的響應得到,而第二個GET請求的地址又由第一個GET的響應得到。
先來模擬第一個POST請求

  1. HttpWebRequest request = null;   
  2. HttpWebResponse response = null;   
  3. string gethost = string.Empty;   
  4. CookieContainer cc = new CookieContainer();   
  5. string Cookiesstr = string.Empty;   
  6. try  
  7. {   
  8.         //第一次POST請求   
  9.     string postdata = "email=" + UserName.Replace("@""%40") + "&password=" + PassWord + "&origURL=" + HostUrl + "&domain=renren.com";//模擬請求數據,數據樣式可以用FireBug插件得到。人人網POST數據時,用戶名郵箱中的“@”變為“%40”,所以我們也要作此變化   
  10.     string  LoginUrl="http://www.renren.com/PLogin.do";   
  11.       request = (HttpWebRequest)WebRequest.Create(LoginUrl);//實例化web訪問類   
  12.     request.Method = "POST";//數據提交方式為POST   
  13.       //模擬頭   
  14.     request.ContentType = "application/x-www-form-urlencoded";   
  15.       byte[] postdatabytes = Encoding.UTF8.GetBytes(postdata);   
  16.       request.ContentLength = postdatabytes.Length;   
  17.       //request.Referer = "http://www.renren.com/Login.do?rf=r&domain=renren.com&origURL=" + HostUrl;   
  18.       request.AllowAutoRedirect = false;   
  19.       request.CookieContainer = cc;   
  20.       request.KeepAlive = true;   
  21.       //提交請求   
  22.     Stream stream;   
  23.       stream = request.GetRequestStream();   
  24.       stream.Write(postdatabytes, 0, postdatabytes.Length);   
  25.       stream.Close();   
  26.       //接收響應   
  27.     response = (HttpWebResponse)request.GetResponse();   
  28.       //保存返回cookie   
  29.       response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);   
  30.       CookieCollection cook = response.Cookies;   
  31.       string strcrook = request.CookieContainer.GetCookieHeader(request.RequestUri);   
  32.       Cookiesstr = strcrook;   
  33.       //取第一次GET跳轉地址   
  34.     StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);   
  35.       string content = sr.ReadToEnd();   
  36.       response.Close();   
  37.       string[] substr = content.Split(new char[] { '"' });   
  38.       gethost = substr[1];   
  39. }   
  40. catch (Exception)   
  41. {   
  42.       //第一次POST出錯;   
  43. }  
HttpWebRequest request = null;
HttpWebResponse response = null;
string gethost = string.Empty;
CookieContainer cc = new CookieContainer();
string Cookiesstr = string.Empty;
try
{
        //第一次POST請求
    string postdata = "email=" + UserName.Replace("@", "%40") + "&password=" + PassWord + "&origURL=" + HostUrl + "&domain=renren.com";//模擬請求數據,數據樣式可以用FireBug插件得到。人人網POST數據時,用戶名郵箱中的“@”變為“%40”,所以我們也要作此變化
    string  LoginUrl="http://www.renren.com/PLogin.do";
      request = (HttpWebRequest)WebRequest.Create(LoginUrl);//實例化web訪問類
    request.Method = "POST";//數據提交方式為POST
      //模擬頭
    request.ContentType = "application/x-www-form-urlencoded";
      byte[] postdatabytes = Encoding.UTF8.GetBytes(postdata);
      request.ContentLength = postdatabytes.Length;
      //request.Referer = "http://www.renren.com/Login.do?rf=r&domain=renren.com&origURL=" + HostUrl;
      request.AllowAutoRedirect = false;
      request.CookieContainer = cc;
      request.KeepAlive = true;
      //提交請求
    Stream stream;
      stream = request.GetRequestStream();
      stream.Write(postdatabytes, 0, postdatabytes.Length);
      stream.Close();
      //接收響應
    response = (HttpWebResponse)request.GetResponse();
      //保存返回cookie
      response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
      CookieCollection cook = response.Cookies;
      string strcrook = request.CookieContainer.GetCookieHeader(request.RequestUri);
      Cookiesstr = strcrook;
      //取第一次GET跳轉地址
    StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
      string content = sr.ReadToEnd();
      response.Close();
      string[] substr = content.Split(new char[] { '"' });
      gethost = substr[1];
}
catch (Exception)
{
      //第一次POST出錯;
}

注釋寫的很詳細了,在這就不再分析,也許有人對request = (HttpWebRequest)WebRequest.Create(LoginUrl)有疑問,可以去google一下HttpWebRequest和WebRequest的區別,簡單來說WebRequest是一個抽象類,不能直接實例化,需要被繼承,而HttpWebRequest繼承自WebRequest。

再模擬第一個和第二個GET請求

  1. try  
  2. {   
  3.     request = (HttpWebRequest)WebRequest.Create(gethost);   
  4.     request.Method = "GET";   
  5.     request.KeepAlive = true;   
  6.     request.Headers.Add("Cookie:" + Cookiesstr);   
  7.     request.CookieContainer = cc;   
  8.     request.AllowAutoRedirect = false;   
  9.     response = (HttpWebResponse)request.GetResponse();   
  10.     //設置cookie   
  11.     Cookiesstr = request.CookieContainer.GetCookieHeader(request.RequestUri);   
  12.     //取再次跳轉鏈接   
  13.     StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);   
  14.     string ss = sr.ReadToEnd();   
  15.     string[] substr = ss.Split(new char[] { '"' });   
  16.     gethost = substr[1];   
  17.     request.Abort();   
  18.     sr.Close();   
  19.     response.Close();   
  20. }   
  21. catch (Exception)   
  22. {   
  23.     //第一次GET出錯   
  24. }   
  25. try  
  26. {   
  27.     //第二次GET請求   
  28.     request = (HttpWebRequest)WebRequest.Create(gethost);   
  29.     request.Method = "GET";  
  30.     request.KeepAlive = true;  
  31.     request.Headers.Add("Cookie:" + Cookiesstr);   
  32.     request.CookieContainer = cc;   
  33.     request.AllowAutoRedirect = false;   
  34.     response = (HttpWebResponse)request.GetResponse();   
  35.     //設置cookie   
  36.     Cookiesstr = request.CookieContainer.GetCookieHeader(request.RequestUri);   
  37.     request.Abort();   
  38.     response.Close();   
  39. }   
  40. catch (Exception)   
  41. {   
  42.     //第二次GET出錯   
  43. }  
try
{
	request = (HttpWebRequest)WebRequest.Create(gethost);
	request.Method = "GET";
	request.KeepAlive = true;
	request.Headers.Add("Cookie:" + Cookiesstr);
	request.CookieContainer = cc;
	request.AllowAutoRedirect = false;
	response = (HttpWebResponse)request.GetResponse();
	//設置cookie
	Cookiesstr = request.CookieContainer.GetCookieHeader(request.RequestUri);
	//取再次跳轉鏈接
	StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
	string ss = sr.ReadToEnd();
	string[] substr = ss.Split(new char[] { '"' });
	gethost = substr[1];
	request.Abort();
	sr.Close();
	response.Close();
}
catch (Exception)
{
	//第一次GET出錯
}
try
{
	//第二次GET請求
	request = (HttpWebRequest)WebRequest.Create(gethost);
	request.Method = "GET";
	request.KeepAlive = true;
	request.Headers.Add("Cookie:" + Cookiesstr);
	request.CookieContainer = cc;
	request.AllowAutoRedirect = false;
	response = (HttpWebResponse)request.GetResponse();
	//設置cookie
	Cookiesstr = request.CookieContainer.GetCookieHeader(request.RequestUri);
	request.Abort();
	response.Close();
}
catch (Exception)
{
	//第二次GET出錯
}

GET與POST請求大同小異,這里便不再累述。三次請求結束,保存好你的cookie string,每次請求的時候都賦給請求的頭部,你就處於登錄狀態了。
人人網的HttpWebRequest登陸模擬很簡單,但是POST及GET涉及到了,是個不錯的案例。
當然,在.net想做自動訪問的操作還可以使用WebBrowser控件,而且還能夠和HttpWebRequest共用cookie,拋磚引玉一下不在本篇文章的討論范圍。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM