新手写的一个12306刷票工具
本来是去年打算写的一个12306的刷票工具,但是一直拖着没完成。过完年才搞好。其实也不算写好,只是感觉都过完年了这个东西都没多大意义,在说各大网站上都有这个功能。但就当记录一下吧。
刚开始写的时候困扰我的其实不是买票的流程,而是如何保持一12306网站的会话,之前在公司做项目的时候一直都是在理论上的,没有真正的接触过网站保持一个session是怎么回事,为此我还特地回去复习了一下这方面的东西,真正感觉到读万卷书不如行万里路。之前一个老鸟跟我过:“这些你不需要现在懂,等你写多了,自然就懂了”
jar包下载连接:https://pan.baidu.com/s/1Btla6KggGXWml168Er0GAQ
好了开始
获取验证图片,至于这个图片的验证数值就是每张图片的坐标。
https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&0.8863164146128835
参数前面的都是固定的,后面的随机数;
验证连接,https://kyfw.12306.cn/passport/captcha/captcha-check
至于这个图片的验证数值就是每张图片的坐标。
登录的链接
https://kyfw.12306.cn/passport/web/login
验证码和用户密码验证完成之后,这里还有一个坑就是下面的几个链接。也要访问一下。
https://kyfw.12306.cn/passport/web/auth/uamtk 这个链接要获取 apptk这个值用于下面的请求;
https://kyfw.12306.cn/otn/uamauthclient
到了这里登录就OK了;
查票的连接,这里经常会出现查不到东西,不知道是我这边的网络问题还其他原因,这样要做好异常处理。
https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=2018-01-24&leftTicketDTO.from_station=GZQ&leftTicketDTO.to_station=EFG&purpose_codes=ADULT
这里的话有就有些字段要根据车次信息用来对。其中一个是车站信息在js文件中获取的。
下一个请求是 https://kyfw.12306.cn/otn/login/checkUser,这个应该是检查用户,如果前面做好了登录的话这里没有必要模拟,我感觉;
提交订单请求
https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest,其中的secretStr这个字段就是前面的车次信息;其他的都很简单,稍微看一下都能懂。
再来就是https://kyfw.12306.cn/otn/confirmPassenger/initDc这个请求:很重要里面有两个字符串是下面请求必须要的;我这里是使用把整个页面弄下来然后用正则表达扣出那几个字符;
REPEAT_SUBMIT_TOKEN
key_check_isChange
就是这两个东西。
再来就是这个https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs。获取人员信息的话我感觉可以在前面登录哪里也可以获取到人员信息。但是我还是重新获取了一遍。
在下一个请求,
https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo
字段信息基本上都是根据上面车次信息对应出来的。需要仔细的看一下车次信息。
再下一个请求 https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount,其中就是leftTicket字段需要用车次信息中字段进行UrlEncode编码一下。其他正常搞。
在下一个连接 https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue, 这里其中就是key_check_isChange字段要通过上面的initDOC获取。其他的都正常拼接。
在下一个连接
https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime?random=1516711514491&tourFlag=dc&_json_att=&REPEAT_SUBMIT_TOKEN=bfadc574d156203cadbb5eb5fe4b0030
其中的random是系统时间,获取就是当放回值 waitCount=0,waitTime=-1,orderId=E685687770是这些值的时候就可以继续下一个连接。顺便把orderId用到下一个请求
在下一个请求
https://kyfw.12306.cn/otn/confirmPassenger/resultOrderForDcQueue
这个最核心的方法:
package com.text.cores;
import java.io.FileNotFoundException; import javax.swing.JTextPane; import org.json.JSONArray; import com.text.utils.MyDateUtil; /** public class Code { private MyKeepLineHttpUtil myKeepLineHttpUtil = new MyKeepLineHttpUtil(); public JSONArray getPassengerInfo() { /** /** validationMap.put("answer", answer); Map<String, String> userInfoMap = new HashMap<>(); json = chenkLoginState(); String uamauthclientURL = "https://kyfw.12306.cn/otn/uamauthclient"; if(stateCode.equals("200")){ /** /** /** /** this.passengerInfo = array; public boolean getTicketIn(String seadInfo, String passenger, String fromStationName, String toStationName, String goTrainDate){ /** } boolean ticketIsHave = false; /** //List<String> seatList = Arrays.asList(seatArray); Map<String, String> sendGET = myKeepLineHttpUtil.sendGET(questTicketURL.toString(), "UTF-8"); jsonResult = jsonData.getJSONArray("result"); } printLog("查询了车票!"); /** String str = split[Integer.parseInt(seatArray[j])]; JSONArray oldPassengersArray = new JSONArray(); printLog("开始获取initDC文件!"); /** JSONArray newPassengersArray = new JSONArray(); String[] usableSeat = map.get("usableSeat").split(","); StringBuffer passengerTicketStr = new StringBuffer(); printLog("开始获取queueCount!"); printLog("confirmSingleForQueue 请求开始!"); String orderSequenceNo = queryOrderWaitTime(repeatSubmitToken); public String queryOrderWaitTime(String RST){ Map<String, String> queryOrderWaitTimeInfo = myKeepLineHttpUtil.sendGET(queryOrderWaitTime.toString(), "UTF-8"); public static void main(String[] args) { } public Code(){ public JTextPane getLogInfo() { public void setLogInfo(JTextPane logInfo) { /** public String parseSeat(String number){ |
登录的界面:
package com.text.view;
import java.awt.EventQueue; import javax.swing.JFrame; import com.text.cores.Code; import javax.swing.JLabel; import java.awt.Font; import javax.swing.Icon; import java.awt.event.ActionListener; public class LoginView extends JFrame { /** private JPanel contentPane; private StringBuffer validatinCodeStr = new StringBuffer(); Code code = new Code(); private void addValidatinCodeStr(String str){ } /** /** JLabel lblNewLabel = new JLabel("12306登录"); JLabel lblNewLabel_1 = new JLabel("用户名:"); userNameText = new JTextField(); JLabel lblNewLabel_3 = new JLabel("密码:"); passwordText = new JPasswordField(); JLabel lblNewLabel_2 = new JLabel(); JButton jb_login = new JButton("登录"); jb_login.setBounds(165, 455, 93, 23); JButton jb_reset = new JButton("重置"); JButton jb_flush = new JButton("刷新验证码"); lblNewLabel_2.addMouseListener(new MouseAdapter() { } private boolean getValidationImg(){ /** URL resource = LoginView.class.getClassLoader().getResource("resource/123.jpg"); jlabel.setIcon(new ImageIcon(img)); /** public static String getJarPath() |
刷票的界面:
package com.text.view;
import java.awt.BorderLayout; import javax.swing.JFrame; import java.awt.Font; import javax.swing.JButton; import java.awt.Color; import javax.swing.JTable; import org.json.JSONArray; import com.text.Entity.TrainInfo; import java.awt.event.MouseAdapter; import javax.swing.table.AbstractTableModel; public class TicketView extends JFrame { /** private Code code; public Code getCode() { public void setCode(Code code) { /** /** JLabel label = new JLabel("出发时间:"); goTrainDate = new JTextField(); JLabel label_1 = new JLabel("--"); JLabel label_2 = new JLabel("返程时间:"); backTrainDate = new JTextField(); JRadioButton rdbtnNewRadioButton = new JRadioButton("单程"); JRadioButton radioButton = new JRadioButton("往返"); JPanel passengerList = new JPanel(); JLabel label_3 = new JLabel("选择要购票的人"); logInfo = new JTextPane(); JLabel label_4 = new JLabel("出发站:"); JLabel lblNewLabel = new JLabel("目的站:"); fromStationName = new JTextField(); JLabel label_5 = new JLabel("--"); toStationName = new JTextField(); JLabel label_6 = new JLabel("系统日志"); JPanel seatList = new JPanel(); JCheckBox chckbxNewCheckBox = new JCheckBox("一等座"); JCheckBox checkBox = new JCheckBox("二等座"); JCheckBox checkBox_1 = new JCheckBox("软卧"); JCheckBox checkBox_2 = new JCheckBox("硬卧"); JCheckBox checkBox_3 = new JCheckBox("硬座"); JCheckBox checkBox_4 = new JCheckBox("无座"); JLabel lblNewLabel_1 = new JLabel("车次信息"); HeroTableModel model = new HeroTableModel(); JScrollPane scrollPane = new JScrollPane(table); JButton jb_questTicket = new JButton("查票"); JButton jb_vieforTicket = new JButton("刷票"); StringBuffer passengerName = new StringBuffer(); String fromStationName = TicketView.this.fromStationName.getText(); } /** /** public TicketView(String user, Code code){ JLabel label = new JLabel("出发时间:"); goTrainDate = new JTextField(); JLabel label_1 = new JLabel("--"); JLabel label_2 = new JLabel("返程时间:"); backTrainDate = new JTextField(); JRadioButton rdbtnNewRadioButton = new JRadioButton("单程"); JRadioButton radioButton = new JRadioButton("往返"); JPanel passengerList = new JPanel(); JLabel label_3 = new JLabel("选择要购票的人"); logInfo = new JTextPane(); JLabel label_4 = new JLabel("出发站:"); JLabel lblNewLabel = new JLabel("目的站:"); fromStationName = new JTextField(); JLabel label_5 = new JLabel("--"); toStationName = new JTextField(); JLabel label_6 = new JLabel("系统日志"); JPanel seatList = new JPanel(); JCheckBox chckbxNewCheckBox = new JCheckBox("一等座"); JCheckBox checkBox = new JCheckBox("二等座"); JCheckBox checkBox_1 = new JCheckBox("软卧"); JCheckBox checkBox_2 = new JCheckBox("硬卧"); JCheckBox checkBox_3 = new JCheckBox("硬座"); JCheckBox checkBox_4 = new JCheckBox("无座"); JLabel lblNewLabel_1 = new JLabel("车次信息"); HeroTableModel model = new HeroTableModel(); JScrollPane scrollPane = new JScrollPane(table); JButton jb_questTicket = new JButton("查票"); JButton jb_vieforTicket = new JButton("刷票"); StringBuffer passengerName = new StringBuffer(); String fromStationName = TicketView.this.fromStationName.getText(); } public void initCode(){ public class HeroTableModel extends AbstractTableModel{ /** public String[] columnNames = new String[] { "车次", "出发时间", "到达时间", "特等座", "一等座", "二等座", "软卧", "硬卧", "硬座", "无座"}; /** /** @Override @Override @Override //return heros[rowIndex][columnIndex]; //返回列名; } public void printLog(String massage){ |
http工具
package com.text.utils;
import java.io.BufferedInputStream; import javax.net.ssl.HostnameVerifier; import org.apache.http.HttpEntity; import com.text.cores.Code; public class MyKeepLineHttpUtil { public CloseableHttpClient httpClient = null; /* /*httpClient = HttpClientBuilder.create() @Override @Override } @Override } private SSLContext getSSLContext(){ private class TrustAllManager implements X509TrustManager { public TrustAllManager() { private Certificate addCertificate(){ CertificateFactory cf = CertificateFactory.getInstance("X.509"); while (bis.available() > 0) { private Certificate addCertificate2(){ @Override @Override @Override } private Registry<ConnectionSocketFactory> getRegistry(){ /** } //添加cookies; public static void main(String[] args) { } |
最后
好了!
新手写的一个12306刷票工具相关推荐
- Python selenium+pyautogui写的一个12306抢票
用selenium+pyautogui写的一个12306抢票 `` 最近处于找工作阶段,在家里闲着无聊,写了一个12306的抢票,还很简陋,也是第一次写文发帖,大佬勿喷. 首先导入模块部分.有些外部库 ...
- 闲来无事写了一个便笺小工具。
一直使用TXQQ的便笺工具,突然这几天发现没有这个功能了. 于是自己写了一个. 能实现基本的功能. 1.关闭时自动保存便签上的内容.下次打开还是该内容 2.靠近最上侧和最右侧时自动隐藏.鼠标靠近时自动 ...
- 怎么用python编写个apk_新手用tkinter写了一个APK提取工具
[Python] 纯文本查看 复制代码""" @author:qh @datetime:2019-3-15 @mood:<(* ̄▽ ̄*)/ "" ...
- 动手写了一个12306插件 chrome浏览器
2019独角兽企业重金招聘Python工程师标准>>> 小生是今年毕业来上海参加工作的一位很普通的java web程序员,后经人介绍转到SAP方向. 以前大学离家相对比较近,都是坐汽 ...
- 用Python写的一个monkeyrunner小工具(支持手机截图与定时截图,手机屏幕的显示)
做软件测试刚好一年了,虽让测试对代码的要求不高,但自己也挺喜欢写代码的 最经在闲暇的时间做了一个monkeyrunner的小工具,支持手机屏幕的动态显示,截图以及定时截图,分享一下: 资源下载地址: ...
- 【Python脚本抢红包】用Python写了一个自动抢红包工具,今年过年准备大干一场
话说又要过年了,现在过年可没有小时候的味道了,小时候只顾着放鞭炮,现在只顾着各个群里蹲红包. 但是手动抢肯定没戏,毕竟手can谁也没办法!那就只能试试能不能通过编程的方式实现自动化抢红包了! 跟小编一 ...
- python 写的一个按键精灵工具 特别方便 喜欢拿去
程序可以每隔固定周期时间自动进行操作鼠标.键盘.输入文本等. 屏幕坐标我是用FastStoneCapture软件的"屏幕十字线"功能取的,很方便,其实方法很多,屏幕截图用画图软件也 ...
- html病毒编写,用bat写的一个小病毒
用了三天才看完=.=,感觉作者整理整理可以把博客当书买了... 然后自己突发其想,想到了一个小病毒程序,其实也算不上病毒,只能算是个恶作剧程序吧,其原理就是不断打开cmd程序,占用系统资源...呵呵. ...
- ❤️女朋友桌面文件杂乱无章?气得我用Python给她做了一个文件整理工具❤️
先看效果图 文章目录 写在前面 文件整理功能 实现 GUI 界面 设置界面主题样式 添加选择路径组件及功能实现 添加"整理","撤销"组件及功能实现 添加输出框 ...
- 写了一个测试正则表达式的小工具
这两天写了两个蜘蛛程序用来自动下载漫画,许多时候都是用他在网页中通过正则表达式获取关键字和信息.我用的正则表达式的工具是Expresso,这个工具无疑是目前最好的正则表达式的工具之一.但用着用着就觉得 ...
最新文章
- 13种编程语言名称的来历
- [LCS]半个月的成果,用RTCClient开发的Robot!
- python opencv 图像网络传输
- 密码检验规则(字母数字和特殊字符组成的混合体)
- NIO 之 FileChannel
- Ubuntu16.04/18.04 安装配置JDK 1.8 环境( Linux )
- Python 基本输出
- Python 文件读和写
- html代码type,HTML中type是什么意思
- DataGrid分页;指定列的总和和平均值;显示鼠标背景色;弹出式窗口;
- [android] android下文件访问的权限
- linux中u盘驱动程序编写,Linux下的硬件驱动——USB设备(下)(驱动开发部分)...
- java生成顺序流水号_Java生成流水号(1)
- 二维数组(动态规划)
- transition属性
- mysql误删除数据恢复处理
- openwrt_ipsec_racoon.init 分析
- IPD的决策评审CDP(2):因地制宜,因时而动
- mysql备份和优化_MySql Innodb存储引擎--备份和优化
- 手机充值时常见问题及解决方法