德广火车票助手登录12306代码详解-登录

TonyWu66 2012-09-28 11:34:32
加精
*以下为内容仅于用技术交流学习,欢迎指教.


/// <summary>
/// 登录
/// </summary>
/// <param name="obj">此参数是为了符合WaitCallback委托的方法签名而设,无实际意义</param>
private void login(object obj)
{
try
{
running = true;
// 等待
sleep();
if (stop == true)
{
return;
}
if (obj != null)
{
Thread.CurrentThread.Name = obj.ToString();
}
if (logged == true)
{
if (MessageBox.Show("您已经登录,您需要再次进入12306网站吗?如果您已经退出,就需要重新登录!", "德广火车票助手 温馨提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
{
this.Invoke(LoggedDelegate);
//openie();
}
running = false;
return;
}

Trace.WriteLine("login()");
count++;
System.Net.ServicePointManager.CertificatePolicy = new MyPolicy();
//通过此路径取得登录需要的loginRand变量的值,随机码.
string uri = "https://dynamic.12306.cn/otsweb/loginAction.do?method=loginAysnSuggest";

string randStr = CommUitl.getString(uri, CommData.cookieContainer);

randStr = randStr.Split(',')[0].Split(':')[1].Replace("\"", string.Empty);


//登录请求提交路径
uri = "https://dynamic.12306.cn/otsweb/loginAction.do?method=login";

// 为参数变量赋值
List<KeyValuePair<string, string>> param = new List<KeyValuePair<string, string>>();
// 随机码
param.Add(new KeyValuePair<string, string>("loginRand", randStr));
// 退票登录
param.Add(new KeyValuePair<string, string>("refundLogin", "N"));
// 退票标识
param.Add(new KeyValuePair<string, string>("refundFlag", "Y"));
// 登录用户名
param.Add(new KeyValuePair<string, string>("loginUser.user_name", txtUserName.Text));
//
param.Add(new KeyValuePair<string, string>("nameErrorFocus", string.Empty));
// 密码
param.Add(new KeyValuePair<string, string>("user.password", txtPassword.Text));
//
param.Add(new KeyValuePair<string, string>("passwordErrorFocus", string.Empty));
// 图形验证码
param.Add(new KeyValuePair<string, string>("randCode", txtVerificationCode.Text));
//
param.Add(new KeyValuePair<string, string>("randErrorFocus", string.Empty));

HttpWebResponse response = null;
try
{
// 提交登录请求
response = HttpWebResponseUtility.CreatePostHttpResponse(uri, param, null, DefaultUserAgent, Encoding.ASCII, cookieCollection, uri);
}
catch (Exception ex)
{
// 显示异常信息
this.Invoke(this.showMsgDelegate, ex.Message);
}

if (response != null)
{
// 得到返回的数据流
Stream receiveStream = response.GetResponseStream();
// 如果有压缩,则进行解压
if (response.ContentEncoding.ToLower().Contains("gzip"))
{
receiveStream = new GZipStream(receiveStream, CompressionMode.Decompress);
}
// 得到返回的字符串
html = new StreamReader(receiveStream).ReadToEnd();
// 进行各种错误判断
if (html.IndexOf("当前访问用户过多") > 0)
{
this.Invoke(this.showMsgDelegate, "当前访问用户过多");
login(null);
}
else if (html.IndexOf("请输入正确的验证码") > 0)
{
messageBoxShowInfo("请输入正确的验证码!");
this.Invoke(focusDelegate, new object[] { txtVerificationCode });
this.Invoke(setControlTextDelegate, new object[] { txtVerificationCode, string.Empty, true });
getVerificationCode(this);
}
else if (html.IndexOf("登录名不存在") > 0)
{
messageBoxShowInfo("登录名不存在!!");
this.Invoke(focusDelegate, new object[] { txtUserName });
}
else if (html.IndexOf("密码输入错误") > 0)
{
messageBoxShowInfo("密码输入错误,如果多次输入错误可能会被锁定帐户!");
this.Invoke(focusDelegate, new object[] { txtPassword });
this.Invoke(setControlTextDelegate, new object[] { txtPassword, string.Empty, true });
}
else if (html.IndexOf("已经被锁定") > 0)
{
messageBoxShowInfo("您的用户已经被锁定,请稍候再试!");
}
else if (html.IndexOf("系统维护中") > 0)
{
//messageBoxShowInfo("系统维护中!");
this.Invoke(this.showMsgDelegate, "系统维护中!");
Thread.Sleep((Int32)numInterval.Value*1000);
login(null);
}
else if (html.IndexOf("我的12306") > 0)
{
// 登录成功,激活窗口,提醒用户
this.Invoke(activateDelegate);
// 记录登录用时及次数
endTime = DateTime.Now;
logged = true;
timeSpan = endTime.Subtract(beginTime);
timeSpanStr = getTimeSpanString(timeSpan);

//MessageBox.Show("经过 " + timeSpanStr + ", " + count + " 次的尝试后,您已经登录成功!" + Environment.NewLine
// + "点击确定打开12306网站,请忽略登录界面,直接点击\"车票预订\"就可以啦!" + Environment.NewLine
// + Environment.NewLine
// + "深圳市德广信息技术有限公司 祝您:" + Environment.NewLine
// + "回家一路顺风!全家身体健康!幸福快乐!事事如意!", "德广火车票助手 恭喜您", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
this.Invoke(this.showMsgDelegate, "登录成功:用"+timeSpanStr + "/" + count + " 次");
// 触发登录成功事件
this.Invoke(LoggedDelegate);
// 修改要发布到微博的默认内容
this.Invoke(shareToWeiboDelegate, new object[] { "我用#德广火车票助手#经过" + timeSpanStr + "尝试登录" + count + "次后,成功登录上了12306.cn!你用了多长时间才登录成功的呢?" });
//openie();
//this.Invoke(this.showMsgDelegate, "登录成功!");
}
else
{
Trace.WriteLine(html);
login(null);
}

Trace.WriteLine(response.StatusCode);
}
else
{
login(null);
}
}
catch (WebException webex)
{
this.Invoke(this.showMsgDelegate, webex.Message);
login(null);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
this.Invoke(setControlTextDelegate, new object[] { btnLogin, "登录", true });
running = false;
}
}
    
源代码请见 :https://code.google.com/p/deguang-tickets-helper
...全文
10363 137 打赏 收藏 转发到动态 举报
写回复
用AI写文章
137 条回复
切换为时间正序
请发表友善的回复…
发表回复
lucw00 2014-04-02
  • 打赏
  • 举报
回复
这个能用mr
rtdthh 2014-02-14
  • 打赏
  • 举报
回复
引用 101 楼 kaka19852008 的回复:
更牛的在这里http://www.fishlee.net/soft/44/index.html
有木鱼版本的源代码没?分享个,亲
happySnow_zhe 2013-01-05
  • 打赏
  • 举报
回复
将学习进行到底……
q107770540 2013-01-05
  • 打赏
  • 举报
回复
yueleixuan 2013-01-05
  • 打赏
  • 举报
回复
是我太笨呢,还是地址不对呢?总之我下载不下来啊!
taoye11 2013-01-01
  • 打赏
  • 举报
回复
谢谢楼主分享,认知学习!!
波西米亚人生 2013-01-01
  • 打赏
  • 举报
回复
谢谢分享
newnazi 2013-01-01
  • 打赏
  • 举报
回复
愚钝 没看明白
liduoduo 2013-01-01
  • 打赏
  • 举报
回复
学习了。不错
  • 打赏
  • 举报
回复
引用 122 楼 fly22098 的回复:
我还没下载源码,就看了下楼主贴的代码,多句嘴,login方法中多个流对象未在方法结束前及时释放对象,HttpWebResponseUtility.CreatePostHttpResponse此方法中肯定是用到HttpWebRequest对象,看不到源码,所以不知是否也需要释放请求对象,虽然是cs程序,针对的是单个用户,影响不大,但是大家都知道,平时登录12306少说也得几……
哪些细节是bug呢? 细节是“死抠”不完的,有时候抠细节是成功之道,有时候抠细节反而是败笔。这并没有什么是非,关键是要理解权衡知道而不要偏执。
失落的神庙 2012-12-30
  • 打赏
  • 举报
回复
引用 36 楼 luanwujian 的回复:
能卖3个亿至少
头像比回答亮
milo_w 2012-12-30
  • 打赏
  • 举报
回复
mark 支持楼主 学习了
zxingdream 2012-10-17
  • 打赏
  • 举报
回复
只是简单的Post过程 没有比较深的逻辑处理
代码质量上 不够严谨 可能仅仅是写着玩的吧
songjinxi123 2012-10-12
  • 打赏
  • 举报
回复
顶一下,很实用的东西。
earon_cao 2012-10-12
  • 打赏
  • 举报
回复
我还没下载源码,就看了下楼主贴的代码,多句嘴,login方法中多个流对象未在方法结束前及时释放对象,HttpWebResponseUtility.CreatePostHttpResponse此方法中肯定是用到HttpWebRequest对象,看不到源码,所以不知是否也需要释放请求对象,虽然是cs程序,针对的是单个用户,影响不大,但是大家都知道,平时登录12306少说也得几十次能买到票算幸运的。只是从程序开发的角度看哈。包含IndexOf方法和Containers方法相比较功能相同,IndexOf只是多出返回索引下标,此处我觉得没有返回下标的意义。直接判断是否存在即可,不知对否,个人做过一点小测试,IndexOf和Containers比较Containers性能较佳。楼主封装Http标头用了一个键值对集合来保存,我觉得是不是可以直接封装一个request请求对象,则直接可以只用,而无需我需要多少个http标头键值则要new多少次KeyValuePair,传到创建请求方法中肯定还要从标头集合中取出赋值给request对象吧?当然这些可能无关紧要的。但个人觉得好程序不仅要好的架构,细节更重要。声明下,没有贬低楼主的意思,只是说说个人见解。
绿领巾童鞋 2012-10-12
  • 打赏
  • 举报
回复
本质上就是HTTP
blackkettle 2012-10-11
  • 打赏
  • 举报
回复
楼主很强大!
hahaliu005 2012-10-11
  • 打赏
  • 举报
回复
好东西
cabriolet8 2012-10-11
  • 打赏
  • 举报
回复
无法获取源代码呀

服务器发送了意外的返回值(405 Method Not Allowed),在响应 “OPTIONS” 的请求
“https://code.google.com/p/deguang-tickets-helper” 中
seominho 2012-10-11
  • 打赏
  • 举报
回复
分享下,,支持。。
加载更多回复(94)

110,545

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧