• 使用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,抛砖引玉一下不在本篇文章的讨论范围。

  • 相关阅读:
    vs2005 pro 在浏览器查看下的一个问题!
    gridview列 数字、货币和日期 显示格式
    验证视图状态 MAC 失败。处理办法!
    vs2005 sp1正式发行!(俗)
    js客户端日历控件
    有人装vs2005的sp1补丁出问题的嚒?
    调查一下 大家用vs时做网页时,都用的什么标准?
    用编码实现gridview的创建!(一)(转www.asp.net)
    怎样在gridview和datalist之类的绑定控件里控制显示 数据省略?
    JQuery上传插件Uploadify使用详解
  • 原文地址:https://www.cnblogs.com/zhwl/p/2396090.html
Copyright © 2020-2023  润新知