C#通过抓包模拟网站用户登录

来源:互联网 发布:js基本数据类型有几种 编辑:程序博客网 时间:2024/06/03 19:03

发现自己真的不会写博客,该有人说了,怎么不会写呢?不是想写什么就写什么吗? 嗯,这个我知道,但是写博客也有它一定的技巧性。有的博客大家给的评价很高,但有的博客大家无人问津,我总结了几点:

一、好的博客必须要有自己的想法,最好不要随便囫囵吞枣的拷贝别人的东西,你可以借鉴,但是还要写出自己的一些见解。尤其像技术博客,当你参见了别人的博客后一定要自己去实践一下,然后把自己的实践方法写出来,这样是最好的。

二、博客要写的通俗易懂,语言诙谐,这个要求我认为是不低的。大多数人都会被这样的博客所吸引。哎呀,我是不是又扯多了啊.......直接入题吧


C# 实现模拟网站用户登录


 之前在网络中总像灌水机器人、抓资源机器人这种程序应该屡见不鲜了。今天就讲解一下它的实现步骤。那么怎么用C#来模拟一个用户的登录呢?要实现用户的登录,那么首先就必须要了解一般网站中是怎么判断用户是否登录的。下边说一些概念性的东西。

HTTP协议是一个无连接的协议(UDP),也就是说这次对话的内容和状态与上次的会话是无关联的,那怎样实现一个浏览器和服务器的持久交互,网站与浏览器之前在刚建立会话时将在服务器内存中建立一个Session,该Session唯一标识了该浏览器,也就是该用户,每一个Session都有一个唯一的ID,第一次建立会话时服务器将生成的这个ID传给浏览器,浏览器在接下来的浏览中每一个发向服务器的请求中都将包含该SessionID,从而标识了自己的身份。

服务器上是使用内存来保存Session中的信息,那么浏览器又使用什么来保存服务器分配的这个SessionID了?对,是Cookie。

在刚建立会话时浏览器向服务器的请求中将不包含SessionID在Cookie中,服务器就认为是一个全新的会话,从而在服务器上分配一段内存给该Session用,同时将该Session的ID在Http Header中使用Set-Cookie发送给浏览器。

原理搞清楚后,那么我们就来实现一个网站的登录嘛,这里就以百度账号的登录为例。

要写这种面向协议的网络程序,抓包工具是少不了的,我们首先是要使用抓包工具分析在普通浏览器中登录时发送和接收的内容才好进一步使用C#来模拟浏览器发包。抓包工具很多,看个人爱好吧,我主要用的是Fiddler,浏览器就用IE吧。

1.最好能清除IE的所有Cookie记录,以免对抓包分析造成影响,然后开启抓包程序。

2.在IE中输入https://passport.baidu.com/?login这个登录地址,然后打开Fiddler抓包工具。

3.输入用户名和密码,点击登录,IE中正常登录,之后我们就要从Fiddler中查找我们要的信息。如图:


又上图可以得到登录后服务器返回的cookie值。

这一步如果由代码实现,如下:

url = new Uri("https://passport.baidu.com/?login");                String postData = "username=" + UserName + "&password=" + PassWord + "&mem_pass=on";CookieContainer container = new CookieContainer();    //新建一个用于保存cookies的容器                   HttpWebResponse webResponse;                byte[] byteRequest = Encoding.GetEncoding("gb2312").GetBytes(postData);//????Encoding.UTF8                httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);                httpWebRequest.ContentType = "application/x-www-form-urlencoded";                httpWebRequest.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/x-silverlight, */*";                httpWebRequest.Referer = "http://passport.baidu.com/?login&tpl=mn&u=http%3A//www.baidu.com/";                httpWebRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E)";                httpWebRequest.Method = WebRequestMethods.Http.Post;//  = "POST";                httpWebRequest.KeepAlive = true;                httpWebRequest.AllowAutoRedirect = true;                httpWebRequest.Headers.Set("Cache-Control", "no-cache");                httpWebRequest.Headers.Set("Accept-Language", "zh-CN");
httpWebRequest.CookieContainer = container;  //返回的cookie会附加在这个容器里面
                //增加下面两个属性即可 解决C# HttpRequest基础连接已经关闭: 接收时发生意外错误                //httpWebRequest.KeepAlive = false;                httpWebRequest.ProtocolVersion = HttpVersion.Version10;                httpWebRequest.ContentLength = byteRequest.Length;                Stream stream;                stream = httpWebRequest.GetRequestStream();                stream.Write(byteRequest, 0, byteRequest.Length);                stream.Close();                webResponse = (HttpWebResponse)httpWebRequest.GetResponse();                #region                if (webResponse.StatusCode == HttpStatusCode.OK)                {                    String cookie1 = webResponse.Headers.Get("Set-Cookie");//GetResponseHeader("Set-Cookie");                    //CookieCollection cookie2 = webResponse.Cookies;                    //Set-Cookie是相当于setAttribute 一样 把静态数据存入到 cookie中                    String src = "";                    for (int i = 0; i < webResponse.Headers.Count; i++)                    {                        src += webResponse.Headers[i] + "\n";                    }                    //getResponseHeader()方法在实际程序中,有时需要从服务器获取一些信息,                    //例如,读取服务器发出信息的首部,读取首部而忽略内容。通过读取首部信息,                    //可以获取到Content-Type(内容类型)、Content-Length(内容长度),                    //甚至Last-Modify(最后一次修改)的日期。                    // 截取bduid                    int a1 = src.LastIndexOf("BAIDUID=");                    src = src.Substring(a1 + 8);                    int a2 = src.IndexOf(":FG=1");                    String bduid = src.Substring(0, a2);                    // 截取bduss                    a1 = src.LastIndexOf("BDUSS=");                    src = src.Substring(a1 + 6);                    a2 = src.IndexOf("; ");                    String bduss = src.Substring(0, a2);                    // 截取userid                    int s1 = cookie1.IndexOf("SAVEUSERID=");                    cookie1 = cookie1.Substring(s1 + 7);                    int s2 = cookie1.IndexOf(";");                    String userid = cookie1.Substring(0, s2);                    if (userid.Trim().Length == 0 || bduid.Trim().Length == 0 || bduss.Trim().Length == 0)                    {                        flag = false;                    }                    else                    {                        USERID = userid;                        BDUSS = bduss;                        BAIDUID = bduid;                        flag = true;                    }

4 获取一个只有登录後才能访问的页面,测试是否登录成功。

HttpWebRequest requestScore = (HttpWebRequest)WebRequest.Create("http://xxxx/xxxx/Score.asp");postData = "term=&TermList=%C7%EB%D1%A1%D4%F1&ckind=&lwPageSize=100&lwBtnquery=%B2%E9%D1%AF";data = encoding.GetBytes(postData);requestScore.Method = "Post";requestScore.ContentType = "application/x-www-form-urlencoded";requestScore.ContentLength = data.Length;requestScore.KeepAlive = true;//使用登陆的cookies通过接下来的验证requestScore.CookieContainer = container; Stream stream = requestScore.GetRequestStream();stream.Write(data, 0, data.Length);stream.Close();HttpWebResponse responseSorce = (HttpWebResponse)requestScore.GetResponse();StreamReader reader = new StreamReader(responseSorce.GetResponseStream(), Encoding.Default);string content = reader.ReadToEnd();

成功登录后,接下来我们只需要每次发送请求是跟上该Cookie,服务器就认为是登录的用户在操作了,接下来就可以Download资源了