分享

使用C#的HttpWebRequest模拟登陆访问人人网

 franklinfj 2013-11-24

使用C#的HttpWebRequest模拟登陆访问人人网

时间:2012-03-15 10:10来源:未知 作者:admin 点击: 496次

无论使用任何语言做模拟登陆或者抓取访问页面,无外乎以下思路:
第一 启用一个web访问会话方法或者实例化一个web访问类,如.net中的HttpWebRequest;
第二 模拟POST或者GET方式提交的数据;
第三 模拟请求的头;
第四 提交请求并获得响应,及对响应做我们所需要的处理。
这里我们以人人网的登录为例,将涉及到POST以及GET两种请求方式。
在之前的文章《免费网页抓包工具,火狐插件FireBug的抓包使用教程》中我们知道,登陆人人网的时候,一共做了一个POST请求以及两个GET请求,如下图:

人人网登录请求

观察这三个请求的详细信息,不难看出第一个GET请求的地址可以由POST的响应得到,而第二个GET请求的地址又由第一个GET的响应得到。
先来模拟第一个POST请求

HttpWebRequest request = null;
  1. HttpWebResponse response = null;
  2. string gethost = string.Empty;
  3. CookieContainer cc = new CookieContainer();
  4. string Cookiesstr = string.Empty;
  5. try
  6. {
  7. //第一次POST请求
  8. string postdata = "email=" + UserName.Replace("@", "%40") + "&password=" + PassWord + "&origURL=" + HostUrl + "&domain=renren.com";//模拟请求数据,数据样式可以用FireBug插件得到。人人网POST数据时,用户名邮箱中的“@”变为“%40”,所以我们也要作此变化
  9. string LoginUrl="http://www.renren.com/PLogin.do";
  10. request = (HttpWebRequest)WebRequest.Create(LoginUrl);//实例化web访问类
  11. request.Method = "POST";//数据提交方式为POST
  12. //模拟头
  13. request.ContentType = "application/x-www-form-urlencoded";
  14. byte[] postdatabytes = Encoding.UTF8.GetBytes(postdata);
  15. request.ContentLength = postdatabytes.Length;
  16. //request.Referer = "http://www.renren.com/Login.do?rf=r&domain=renren.com&origURL=" + HostUrl;
  17. request.AllowAutoRedirect = false;
  18. request.CookieContainer = cc;
  19. request.KeepAlive = true;
  20. //提交请求
  21. Stream stream;
  22. stream = request.GetRequestStream();
  23. stream.Write(postdatabytes, 0, postdatabytes.Length);
  24. stream.Close();
  25. //接收响应
  26. response = (HttpWebResponse)request.GetResponse();
  27. //保存返回cookie
  28. response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
  29. CookieCollection cook = response.Cookies;
  30. string strcrook = request.CookieContainer.GetCookieHeader(request.RequestUri);
  31. Cookiesstr = strcrook;
  32. //取第一次GET跳转地址
  33. StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
  34. string content = sr.ReadToEnd();
  35. response.Close();
  36. string[] substr = content.Split(new char[] { '"' });
  37. gethost = substr[1];
  38. }
  39. catch (Exception)
  40. {
  41. //第一次POST出错;
  42. }
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请求

try
  1. {
  2. request = (HttpWebRequest)WebRequest.Create(gethost);
  3. request.Method = "GET";
  4. request.KeepAlive = true;
  5. request.Headers.Add("Cookie:" + Cookiesstr);
  6. request.CookieContainer = cc;
  7. request.AllowAutoRedirect = false;
  8. response = (HttpWebResponse)request.GetResponse();
  9. //设置cookie
  10. Cookiesstr = request.CookieContainer.GetCookieHeader(request.RequestUri);
  11. //取再次跳转链接
  12. StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
  13. string ss = sr.ReadToEnd();
  14. string[] substr = ss.Split(new char[] { '"' });
  15. gethost = substr[1];
  16. request.Abort();
  17. sr.Close();
  18. response.Close();
  19. }
  20. catch (Exception)
  21. {
  22. //第一次GET出错
  23. }
  24. try
  25. {
  26. //第二次GET请求
  27. request = (HttpWebRequest)WebRequest.Create(gethost);
  28. request.Method = "GET";
  29. request.KeepAlive = true;
  30. request.Headers.Add("Cookie:" + Cookiesstr);
  31. request.CookieContainer = cc;
  32. request.AllowAutoRedirect = false;
  33. response = (HttpWebResponse)request.GetResponse();
  34. //设置cookie
  35. Cookiesstr = request.CookieContainer.GetCookieHeader(request.RequestUri);
  36. request.Abort();
  37. response.Close();
  38. }
  39. catch (Exception)
  40. {
  41. //第二次GET出错
  42. }
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,抛砖引玉一下不在本篇文章的讨论范围。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多