相信园子里也有不少玩开心网的朋友,但为了玩的更顺心,所以我开发了一款开心网辅助工具,可以自动进行操作。
现在为了开发出更强大的功能,所以今天讲解一下原理及我已经封装好的所有类库,希望你能加入我开发更多的插件!
准备工具:WSockExpert(用于抓包)
原理:分析出开心网的所有操作连接,通过程序模拟请求进行批量操作!
今天拿开心网登陆做例子,并用程序进行模拟登陆。
选择好监听页面后从浏览器进行登陆操作。
点击登陆按钮后,抓包程序就会有变化了,因为刚才我们进行了与开心网服务器交互动作,需要向外发送数据,所以通过抓包数据得到了如下结果:
POST /login/login.php HTTP/1.1
Accept: application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Referer: http://www.kaixin001.com/
Accept-Language: zh-CN
Content-Type: application/x-www-form-urlencoded
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 2.0.50727; CIBA)
Host: http://www.kaixin001.com/
Content-Length: 48
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: _uid=2121099; SERVERID=_srv134-110_
mailto:url=%2F&email=dirain**@yahoo.cn&password=19920226
/login/login.php,就是登陆的请求地址,全部连接应该是:http://www.kaixin001.com/login/login.php。
最底部的mailto:url=%2F&email=dirain**@yahoo.cn&password=19920226 应该就是传递的参数,我们可以看到,只提交了帐号和密码为参数,请求类型为POST。
得到了这些信息,就可以通过C#的WebRequest去模拟一个请求,实现登陆操作,代码也很简单。
模拟请求的方法
模拟POST请求
/// <summary>
/// 发送Post类型请求
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="postData">参数</param>
/// <returns></returns>
public WebResponse doPost(string url,string postData)
{
try
{
System.GC.Collect();
Thread.Sleep(this.defer);
byte[] paramByte = Encoding.UTF8.GetBytes(postData); // 转化
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Referer = "http://www.kaixin001.com/app/app.php?aid=1040";
webRequest.Accept = "application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-silverlight, */*";
webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; CIBA)";
webRequest.ContentLength = paramByte.Length;
webRequest.CookieContainer = this.cookies;
//webRequest.Timeout = 5000;
Stream newStream = webRequest.GetRequestStream();
newStream.Write(paramByte, 0, paramByte.Length); //写入参数
newStream.Close();
return webRequest.GetResponse();
}
catch (Exception ce)
{
throw ce;
}
}
在模拟请求中需要注意的是同步Cookie,否则没有办法维持session。
webRequest.CookieContainer = this.cookies;
这句话就是维持session的关键代码,this.cookies是一个非局部变量,这样保证每次调用的时候都可以使用上次操作时的cookie。
Code
/// <summary>
/// 与请求相关的cookie(用于保持session)
/// </summary>
protected CookieContainer cookies = new CookieContainer();
只要每次请求的时候把Webrequest对象的CookieContainer 属性赋值为已经声明好的 CookieContainer对象,而不是重新实例化。
登陆开心网
登陆开心网
/// <summary>
/// 登陆开心网
/// </summary>
/// <param name="account">用户名</param>
/// <param name="password">密码</param>
/// <returns>用户个人信息</returns>
public virtual UserInfoEntity Login(string account,string password)
{
try
{
//拼凑登陆参数
string param = "url=/home/&invisible_mode=0&email=" + account + "&password=" + password;
WebResponse response = this.doPost("http://www.kaixin001.com/login/login.php",param);
StreamReader streamReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
//如果返回地址为home页,则说明登陆成功
if (response.ResponseUri.ToString() == "http://www.kaixin001.com/home/")
{
//读取返回的流
string body = streamReader.ReadToEnd();
//如果存在如下信息则登陆失败
if (body.IndexOf("帐号或密码不太对吧! 重试一次?") != -1)
{
return null;
}
else
{
//登陆成功后执行
//
}
}
else
{
response.Close();
streamReader.Close();
}
}
catch
{
}
}
这是个简单的模拟请求登陆代码,其实做WEB程序的辅助工具,重要的就是分析数据,这个例子中最重要的步骤还是用抓包工具去抓取开心网的提交方式以及传递参数。如果你不用抓包工具去抓取你也可以通过分析html表单来获取传递方式,但这样会很麻烦。
总结一下过程其实很简单,分析提交到服务器的URL,通过程序模拟请求去操作,然后得到服务器返回结果通过提取网页内容的方式达到我们想实现的效果。