c# 模拟 网页实现12306登陆、自动刷票、自动抢票完全篇(转)

这一篇文章,我将从头到尾教大家使用c#模拟网页面登陆12306网站,自动刷票,选择订票人,到最后一步提交订单。研究过HTTP协议的童鞋们都 知道,我们在访问网站时,是有两种方式的,POST和GET方式,HTTP协议是TCP/IP的一部分,有兴趣的可以使用Socket通讯可以模拟出 HTTP的访问机制。我们再说POST和GET方式,在访问一个页面时,浏览器会提交一个本地cookie提交到网站服务器,cookie的作用可以是保 存我们登陆网站成功后取得的一串钥匙,也可以是其他的一些重要的信息。这是至关重要的一步。让我们步入正题。

我们来了解12306的登陆方式,我们使用http跟踪发现他的登陆的地址

https://kyfw.12306.cn/otn/login/loginAysnSuggest

在登陆过过程中提交了一个表单数据,包括loginserDTO.user_name、userDTO.password、randCode。我第一次看见时都有点悲催了,这么一个大的网站,密码传输竟然是明文的..

第一个参数是我们的用户名、第二是密码、第三个是校验码。

接下来我们要做的就是获取登陆验证码了。我们看到验证码的地址是

这是一个图片的地址,我们将这个图片地址指向我们的picturebox控件的Image路径。最终的登陆界面是这样的

新建一个HttpWebRequestExtension.cs 类,加入我们核心代码,包括提交订单数据,获取网页内容,获取校验码图片。

/// <summary>
    /// 模拟网页操作,提交、获取订单页面数据
    /// </summary>
    public class HttpWebRequestExtension
    {
        private static string contentType = "application/x-www-form-urlencoded";
        private static string accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight-2-b1, */*";
        private static string userAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; Zune 4.7; BOIE9;ZHCN)";
        private static string referer = "https://kyfw.12306.cn/";
        /// <summary>
        /// 提交订单数据
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cookie"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public static string PostWebContent(string url, CookieContainer cookie, string param)
        {
            byte[] bs = Encoding.ASCII.GetBytes(param);
            var httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
            httpWebRequest.CookieContainer = cookie;
            httpWebRequest.ContentType = contentType;
            httpWebRequest.Accept = accept;
            httpWebRequest.UserAgent = userAgent;
            httpWebRequest.Method = "POST";
            httpWebRequest.ContentLength = bs.Length;
            using (Stream reqStream = httpWebRequest.GetRequestStream())
            {
                reqStream.Write(bs, 0, bs.Length);
            }
            var httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            Stream responseStream = httpWebResponse.GetResponseStream();
            StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8);
            string html = streamReader.ReadToEnd();

            streamReader.Close();
            responseStream.Close();

            httpWebRequest.Abort();
            httpWebResponse.Close();

            return html;
        }

        /// <summary>
        /// 获取页面数据
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cookie"></param>
        /// <returns></returns>
        public static string GetWebContent(string url, CookieContainer cookie)
        {
            var httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
            httpWebRequest.CookieContainer = cookie;
            httpWebRequest.ContentType = contentType;
            httpWebRequest.Referer = referer;
            httpWebRequest.Accept = accept;
            httpWebRequest.UserAgent = userAgent;
            httpWebRequest.Method = "GET";
            httpWebRequest.ServicePoint.ConnectionLimit = int.MaxValue;

            var httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            Stream responseStream = httpWebResponse.GetResponseStream();
            StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8);
            string html = streamReader.ReadToEnd();

            streamReader.Close();
            responseStream.Close();

            httpWebRequest.Abort();
            httpWebResponse.Close();

            return html;
        }

        /// <summary>
        /// 获取网页验证码图片
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cookie"></param>
        /// <returns></returns>
        public static object GetWebImage(string url, CookieContainer cookie)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Referer = referer;
            request.UserAgent = "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36";
            request.Accept = "image/webp,*/*;q=0.8";
            request.CookieContainer = cookie;
            request.ContentType = contentType;
            request.KeepAlive = true;
            request.UseDefaultCredentials = true;
          //  request.Proxy = null;
            return request.GetResponse().GetResponseStream();
        }
    }

然后我们就可以模拟登陆12306了。

var loginRes = HttpWebRequestExtension.PostWebContent(TrainUrlConstant.AsynSugguestUrl, cookieContainer,

                              "loginUserDTO.user_name=" + userLogin.UserName + "&&userDTO.password=" + userLogin.Password + "&&randCode=" + userLogin.VerifyCode

                              );

登陆的结果是以JSON数据格式返回的。如果你看到有 loginCheck\":\"Y\",那么恭喜,你已经登陆上网站了。

如果失败了也无妨,返回的结果可以看到登陆失败的原因,message:[“..”], ...表示返回的错误原因,这里就不一一列出了。

注意:登陆成功后保存cookie的状态,前面强调过这是最重要的一个环节。

然后获取车站信息。车站信息保存在一个JS里面,我们需要解码JS。

https://kyfw.12306.cn/otn/resources/js/framework/station_name.js

大家使用浏览器打开看看,里面是不是一个定义好的以|分隔的车站信息,我们只需要提取出车站名称和车站编码。以下是我的解码方式。

再进一下获取购票人信息,我们的联系人的URL是 https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs,这是一个JSON数据。

JSON数据里面包含有所有联系人的信息内容,包括电话、身份证号、出生年月、是否学生、性别等。有了这些基础数据我们就可以刷票、购票了。让我们先看看剩余的票数吧

https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT

URL里面传递的数据有始发站、终点站、出发日期等信息。 我们使用Get 方式获取余票信息

 var url = string.Format(TrainUrlConstant.TrainleftTicketInfo, startTime, from, to);

            var trainleftTicketInfoRes = HttpWebRequestExtension.GetWebContent(url, cookieContainer);

返回的JSON数据里面包含有车票的标志位,也就是上图的secretStr,还有出发时间、软卧数、硬卧数、软座、硬座数等。

有了这些数据 我们就可以选择自动刷票了。

接下来选定好坐席,车次开始抢票。

选中车次后 确认提交我们选中的车次信息,我们看一下他需要传的参数信息

12306提交订单使用的是一个订单一个随机的token信息,那么在这之前我们就必须先要获取Token信息了

那么这个表单里面的token、key_check_ischange、leftTicketStr、train_location从哪里来呢?这 就到了考验耐心的时候了,经过仔细的查找发现,原来这些信息是隐藏在网页的JS里面。页面地址是 https://kyfw.12306.cn/otn/confirmPassenger/initDc 不仔细看还真看不出来啊。

var submitPassagerRes = HttpWebRequestExtension.PostWebContent(TrainUrlConstant.SubmitOrderInitialUrl, cookieContainer, "_json_att=");

另外两个参数passengerTicketStr、oldPassengerStr 是我们选中购票人,仔细分析这串字符串,发现其中是有规律的,每一个购票人是以_分隔的。逗号前第一个数据代表的是座席号,逗号的第四个数据是联系人,记 住需要用URL编码格式,第6个是身份证号,第7个是手机号。

然后再获取提交订单前的校验码 https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=passenger&rand=randp

pbxOrderCode.Image = Image.FromStream((Stream)HttpWebRequestExtension.GetWebImage(TrainUrlConstant.OrderValidateCodeUrl, cookie));

将我们上面找出来的表单信息提交到网站校验是不是有问题

正确的订单返回的结果

如果以上都没有问题的话,接下来就可以进入到真正意义的抢票过程了。我们看一下抢票的URL

https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue

就差最后一步了。我们看看是不是生成订单号了。

看看返回的JSON结果里面有没有orderID,当orderID大于0,表示你的票已经抢到手了。赶紧登陆网站付款去吧。

c# 模拟 网页实现12306登陆、自动刷票、自动抢票完全篇(转)

时间: 2024-10-20 13:39:45

c# 模拟 网页实现12306登陆、自动刷票、自动抢票完全篇(转)的相关文章

Python3.6实现12306火车票自动抢票,附源码

Python(发音:英[?pa?θ?n],美[?pa?θɑ:n]),是一种面向对象.直译式电脑编程语言,也是一种功能强大的通用型语言,已经具有近二十年的发展历史,成熟且稳定.它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务.它的语法非常简捷和清晰,与其它大多数程序设计语言不一样,它使用缩进来定义语句. Python支持命令式程序设计.面向对象程序设计.函数式编程.面向切面编程.泛型编程多种编程范式.与Scheme.Ruby.Perl.Tcl等动态语言一样,Python具备垃圾回收

python3.7之12306抢票脚本实现

悲催的12306,彻底沦为各路抢票软件的服务提供方.元旦伊始,纯粹12306官网及APP抢票,愈一周的时间,仅到手一张凌晨3:55回家的站票.为远离脑残,无奈选择抢票软件,预购年后返沪车票.BTW,研究一下抢票脚本的实现思路,参考:(https://juejin.im/post/5b116504f265da6e0636cbc2 - Python3.6实现12306火车票自动抢票). 在原作者之上,对执行代码做了以下处理: 删除短信/邮件通知功能 删除控制台输入功能 新增登陆cookie的刷新 新

谈网页游戏外挂之用python模拟游戏(热血三国2)登陆

看web看多了,想写写页游的外挂,其实原理是一样的,就是端口不一样协议字段你不知道,而这也提高了点技术门槛,看我们来一点一点突破这些门槛,这次我们来用python发包模拟flash的客户端登陆. 以热血三国2为例,热血三国2是一款balabalaba自己查去吧的游戏. step1 : 在sg2.ledu.com注册个账户  略过...step2 : 登陆游戏,wireshark抓包分析    以双线784服为例,游戏页面地址http://s784.sg2.ledu.com/,现在游戏一般都是联运

抢票助手-for 12306买火车票.订票助手.高铁.动车.春运.车票管家.自动刷票.列车时刻表

下载地址:https://itunes.apple.com/cn/app/id821884019?mt=8 完全免费 1.无代理费.无保险费,无任何附加费用: 2.无任何功能限制.无使用次数限制: 强大的功能 1.抢票专家:超强抢票功能,每隔1s为您刷票: 2.上车补票:同时为您查询全程票和半程票,让您顺利回家过年: 3.完善的功能:查询余票.购票支付.改签.退票: 4.多种支付方式:支付宝.中国银联.建行.工行.农行.招商银行... 5.回家过年.探亲访友.外出旅游,抢票必备app: 6.支付

12306登陆接口更改后的随机参数的获取

登录时截获发送的数据包如图: 上图画红圈的就是12036系统生成的随机参数,每次登陆参数名称不一样,值也不一样,如果登陆没有这个参数的话,那肯定是不能成功的.那如何获取到这个随机参数呢? 用抓包工具抓某一刷票软件的登陆的http请求,结果发现它访问了一个js,js地址为:https://kyfw.12306.cn/otn/dynamicJs/ljrkadr,于是找到了js代码,格式化了下如下: var submitForm; (function($) { var jq = $.ajax; fun

利用Node.js实现模拟Session验证的登陆

1.身份验证和用户登陆 在一般的Web应用上,如果要实现用户登陆,最常用,也是最简单的方法就是使用Session,基本的思路是在Session中保留一些用户身份信息,然后每次在Session中取,如果信息不正确或不存在,那么身份验证失败,正确则成功. Session和Cookie是两个很相似的东西,都是字符串,只不过Session是保存在服务器上的,而Cookie是保存在本地的,所以Cookie是不能用作身份验证的.Session故名思议,肯定和客户端与服务器间建立的会话相关,Session的工

让网页背景图片 根据屏幕大小自动铺满

让网页背景图片 根据屏幕大小自动铺满:设置两层div,底层div当做背景使用,放置一张图片即可.<div id="background" style="position:absolute;z-index:-1;width:100%;height:100%;top:0px;left:0px;"><img src="1.jpg" width="100%" height="100%"/>&

winform中webBrowser模拟网页操作中遇到的问题

我们通过网页上传一些特殊数据的时候,由于必填项众多,数量量大的时候,会发现工作相当繁琐,前段时间做了一个winform内嵌webBrowser模拟网页上传文档的小工具,发现了许多问题,总结一下: 先说明的是文档是用Excel指定格式制成的表格,数据是通过循环表格数据行上传的. 需求是如果文档已经上传那么必须提示,但上传成功不必提示(因为循环上传的话会弹出很多提示框). 代码如下:添加引用 在扩展程序集中找到Microsoft.mshtmlusing mshtml; 在窗体类上面贴标签: [Com

使用Python和Splinter实现12306火车票查询与抢票

有一段时间没有使用Python了,前几天经朋友提起一篇关于用Python实现抢火车票的文章,百度了实现抢火车票的技术细节,网上却有不少资料,也不是新鲜的东西.在了解了一些技术手段,阅读了一些大神的博文后,也尝试实现了一下,代码写得粗糙,纯当娱乐,本文在Windows系统下完成.需要提到的是,抢票过程中的验证码部分只能手动完成. 首先,我需要的工具和组件有: Chrome浏览器 浏览器驱动ChromeDriver Python 3.5 Web应用测试工具Splinter Chrome浏览器可自行下