晓查 郭一璞 发自凹非寺
量子位 报道 公众号 QbitAI
今天,已经可以抢过完年回来的火车票了。
如果你对自己手速和市面上的各种“加速包”都没什么信心的话,不妨试试用程序员的手段抢票?
况且,12306 官方宣布屏蔽了一大批付费抢票软件,这也意味着你即使给这些软件付了会员费,也依旧抢不到票。
所以只能回到最初的手动抢票?No!No!No!
GitHub 上有两个“年经”项目,每到春运前一段时间,就会定时定点的登顶热榜,助力一代又一代程序员和姿势丰富的非程序员们抢票回家。
那么,这两个项目究竟怎么用?好不好用?
和手动抢票、第三方软件抢票比起来优势是否明显?
安装使用过程中,会不会遇到不可名状的 bug?
今天为大家一一横评。
一、霸占热榜的两个项目
排在 GitHub 热榜第 1 的项目名字简单粗暴,就直接叫12306,已经有 21300 星,来自 ID 为 testerSunshine 的作者。
testerSunshine 的 12306 项目可以自动登录用户账户,能卡点抢票,也能捡漏候补,抢到票后会通过邮件进行通知。
排在热榜第 2 位的,叫做py12306,目前已有 8300 星,今年初就已经非常火了。
二、我该选哪个抢票软件
那么整体来看,这两款开源软件,哪个更好用呢?
py12306 从去年开始就已经被大家广泛使用,其优点是设置比较简洁,甚至还有图形界面。但是它在验证码登录过程中容易出现下载失败的情况,如果把打码接口从 free 换成“若快”平台,还需要充值。
如果你对运行代码一无所知,建议使用 py12306.
testerSunshine 的 12306 插件设置比较复杂,自动获取 cookie 经常失败,因此需要手动填写,这一点比不上 py12306;但是它自带了开发者的 12306 图片识别模型,我们可以在本地完成图片识别码的登录过程。
从实际使用效果来看,我们更推荐 testerSunshine 的 12306,目前它在 GitHub 上的高人气,也反映的用户们的选择。
测评细节&使用教程
两个抢票插件的关键都在配置文件的修改:testerSunshine/12306 的关键在于 TickerConfig.py,
而 py12306 的关键在于 env.py。
热榜第一:12306
我们先开始测试现在趋势榜第一的 12306,先将项目复制到本地:
1 2 | git clone https:<span style="color: #008000;">//</span><span style="color: #008000;">github.com/testerSunshine/12306</span> cd <span style="color: #800080;">12306</span> |
再安装依赖项,为了避免多 python 环境产生问题,建议以 root 用户方式安装:
1 | pip3 <span style="color: #0000ff;">install</span> -i https:<span style="color: #008000;">//</span><span style="color: #008000;">pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt</span> |
下面到了整个过程最关键的环节,配置 TickerConfig.py 文件,这一步将决定你的成败!非常重要!
看到配置文件里一长串字符,你是不是觉得很头疼呢?我们经过测试,找到了其中的几个关键点:
1、如果你没有抢到票,寄希望于其他人退票后捡漏,令 TICKET_TYPE = 2,否则设置为1;
1 2 | # 刷票模式:<span style="color: #800080;">1</span>=刷票 <span style="color: #800080;">2</span>=候补+<span style="color: #000000;">刷票 TICKET_TYPE </span>= <span style="color: #800080;">1</span> |
TICKET_TYPE = 1
2、STATION_TRAINS可以填入一串你想要抢的车次,比如北京到合肥方向,你想购买 G267、G29 次列车,就设置为 STATION_TRAINS = [“G267”, “G29”],中间用逗号隔开,不填写等于抢当日全部车次;
1 2 3 4 5 6 7 8 9 | # 出发日期(list) <span style="color: #800000;">"</span><span style="color: #800000;">2018-01-06</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">2018-01-07</span><span style="color: #800000;">"</span><span style="color: #000000;"> STATION_DATES </span>=<span style="color: #000000;"> [ </span><span style="color: #800000;">"</span><span style="color: #800000;">2020-01-30</span><span style="color: #800000;">"</span><span style="color: #000000;"> ] # 填入需要购买的车次(list),</span><span style="color: #800000;">"</span><span style="color: #800000;">G1353</span><span style="color: #800000;">"</span><span style="color: #000000;"> # 修改车次填入规则,注:(以前设置的车次逻辑不变),如果车次填入为空,那么就是当日乘车所有车次都纳入筛选返回 # 不填车次是整个 list 为空才算,如果不是为空,依然会判断车次的,这种是错误的写法 [</span><span style="color: #800000;">""</span><span style="color: #000000;">], 正确的写法 [] STATION_TRAINS </span>= [<span style="color: #800000;">"</span><span style="color: #800000;">G267</span><span style="color: #800000;">"</span>,<span style="color: #800000;">"</span><span style="color: #800000;">G29</span><span style="color: #800000;">"</span>] |
3、STATION_DATES填入你出发的日期,这一步不难;
4、出发站 FROM_STATION 和到达站 TO_STATION 不必精确到具体的站,只需填入城市,除非你想从特定站点出发;
1 2 3 4 5 | <span style="color: #000000;"># 出发城市,比如深圳北,就填深圳就搜得到 FROM_STATION </span>= <span style="color: #800000;">"</span><span style="color: #800000;">北京</span><span style="color: #800000;">"</span><span style="color: #000000;"> # 到达城市比如深圳北,就填深圳就搜得到 TO_STATION </span>= <span style="color: #800000;">"</span><span style="color: #800000;">合肥</span><span style="color: #800000;">"</span> |
5、乘车人填入你 12306 账号中常用联系人的姓名,比如 TICKET_PEOPLES = [“张三”],如果没有,需要登录 12306 手动添加;
1 2 3 4 | <span style="color: #000000;"># 乘车人(list) 多个乘车人 ex: # </span><span style="color: #800000;">"</span><span style="color: #800000;">张三</span><span style="color: #800000;">"</span><span style="color: #000000;">, # </span><span style="color: #800000;">"</span><span style="color: #800000;">李四</span><span style="color: #800000;">"</span><span style="color: #000000;"> TICKET_PEOPLES </span>= [<span style="color: #800000;">"</span><span style="color: #800000;">李雷</span><span style="color: #800000;">"</span>,<span style="color: #800000;">"</span><span style="color: #800000;">韩梅梅</span><span style="color: #800000;">"</span>] |
6、填入你的 12306 账户名和密码;
1 2 3 | <span style="color: #000000;"># 12306 登录账号 USER </span>= <span style="color: #800000;">"</span><span style="color: #800000;">Lilei</span><span style="color: #800000;">"</span><span style="color: #000000;"> PWD </span>= <span style="color: #800000;">"</span><span style="color: #800000;">123456</span><span style="color: #800000;">"</span> |
7、如果不需要邮箱和 Server 酱提醒,请把 EMAIL_CONF 和 SERVER_CHAN_CONF 的第一项都设置为 False;
8、开放抢票时间根据自己车次填入,可以提前几秒,比如下午一点开发抢票,则填入 OPEN_TIME = “12:29:57” ;
1 2 | <span style="color: #000000;"># 预售放票时间, 如果是捡漏模式,可以忽略此操作 OPEN_TIME </span>= <span style="color: #800000;">"</span><span style="color: #800000;">12:29:57</span><span style="color: #800000;">"</span> |
9、cookie 设置这一步尤为关键,经过我们实测,COOKIE_TYPE 设置为 1 或 2 都有些问题,建议设置为3;
1 2 3 4 | # <span style="color: #800080;">1</span>=<span style="color: #000000;">使用 selenium 获取 devicesID # </span><span style="color: #800080;">2</span>=使用网页端/otn/HttpZF/<span style="color: #000000;">logdevice 获取 devicesId,这个接口的算法目前可能有点问题,如果登录一直 302 的请改为配置 1 # </span><span style="color: #800080;">3</span>=自己打开浏览器在 headers-<span style="color: #000000;">Cookies 中抓取 RAIL_DEVICEID 和 RAIL_EXPIRATION,这个就不用配置 selenium COOKIE_TYPE </span>= <span style="color: #800080;">3</span> |
10、上一步设置为 3 以后,还需要手动设置后面的两个参数RAIL_EXPIRATION和RAIL_DEVICEID。
1 2 3 4 5 | # 如果 COOKIE_TYPE=<span style="color: #800080;">3</span><span style="color: #000000;">, 则需配置 RAIL_EXPIRATION、RAIL_DEVICEID 的值 RAIL_EXPIRATION </span>= <span style="color: #800000;">"</span><span style="color: #800000;">1577327361278</span><span style="color: #800000;">"</span><span style="color: #000000;"> RAIL_DEVICEID </span>= <span style="color: #800000;">"</span><span style="color: #800000;">jFAKbAeAInPnm0pAdqdCNG0ID_dU6SW6L8gaX7zDEewcWVJC5w7nTSw63oMK9sd9c6FcdhyDMsuVUV4aknfXwzHhO8c_Z-nLU4W8F4_gj_HlrOrsrR29U82HR4pnMRqoRFBKuCZ3tKAgQrhuYnR5RWsBCe5g7goV</span><span style="color: #800000;">"</span><span style="color: #000000;"> # RAIL_EXPIRATION </span>= <span style="color: #800000;">"</span><span style="color: #800000;">1577034103293</span><span style="color: #800000;">"</span><span style="color: #000000;"> # RAIL_DEVICEID </span>= <span style="color: #800000;">"</span><span style="color: #800000;">CDno29Erc_Pf3FSXb4dzq-Op64EhWrsi5yUZKVIKR1MAfYo2qFlCeXD8VkexY7_1qg-ClV-fE8j9jgVlPZxRh3wVc2iqLe_5A8sdr62qZx4B22JPF8lFCjpgTKZ5ODW90HJd5tiQsJ1KR9nOqHRxHj1FT5LEIwfw</span><span style="color: #800000;">"</span> |
如何找到这两个参数?先用 Chrome 浏览器打开 12306.cn,点击网站地址左边的“锁形”图标:再点击下发的 Cookie
接着会出现一组 Cookie,选择来自 12306.cn 的 Cookie:
看到RAIL_EXPIRATION和RAIL_DEVICEID两个参数,点击它,将内容里的一串字符复制到配置文件中。
需要注意的是 RAIL_DEVICEID 参数很长,可能显示不全,请完整复制。
至此,准备工作已全部完成,启动前请先筛选 cdn,这点很重要!
1 | python3 run.py c |
接着启动服务:
1 | python3 run.py r |
接着它会提出登录成功,并列出当日所有相关车次信息,然后开始抢票:
抢票成功后,这个软件不能帮你完成支付,你还需要在手机或者电脑上登录 12306 网站,在 30 分钟内完成支付动作,否则你辛辛苦苦抢的票就没了。
热榜第二:py12306
py12306 的安装方式与前者类似:
1 2 3 | git clone https:<span style="color: #008000;">//</span><span style="color: #008000;">github.com/pjialin/py12306</span> <span style="color: #000000;">cd py12306 pip3 install </span>-r requirements.txt |
然后修改配置文件,现更改后缀名
1 | cp env.py.example env.py |
默认配置文件中需要修改的选项有:
1、你的 12306 账户和密码;
1 2 3 4 5 6 7 8 | # <span style="color: #800080;">12306</span><span style="color: #000000;"> 账号 USER_ACCOUNTS </span>=<span style="color: #000000;"> [ # 目前已支持仅查询,不下单,屏蔽掉下面的账号即可 { </span><span style="color: #800000;">'</span><span style="color: #800000;">key</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">lilei</span><span style="color: #800000;">'</span><span style="color: #000000;">, # 如使用多个账号 key 不能重复 </span><span style="color: #800000;">'</span><span style="color: #800000;">user_name</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">Lilei</span><span style="color: #800000;">'</span><span style="color: #000000;">, </span><span style="color: #800000;">'</span><span style="color: #800000;">password</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">123456</span><span style="color: #800000;">'</span><span style="color: #000000;"> },</span> |
2、查询任务 QUERY_JOBS 中的各项参数,包括出发日期 left_dates、出发站 left 和到达站 arrive、乘客姓名 members、坐席 seats、车次 train_numbers;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <span style="color: #000000;"># 查询任务 QUERY_JOBS </span>=<span style="color: #000000;"> [ { # </span><span style="color: #800000;">'</span><span style="color: #800000;">job_name</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">bj -> yl</span><span style="color: #800000;">'</span><span style="color: #000000;">, # 任务名称,不填默认会以车站名命名,不可重复 </span><span style="color: #800000;">'</span><span style="color: #800000;">account_key</span><span style="color: #800000;">'</span>: <span style="color: #800080;">0</span><span style="color: #000000;">, # 将会使用指定账号下单 </span><span style="color: #800000;">'</span><span style="color: #800000;">left_dates</span><span style="color: #800000;">'</span><span style="color: #000000;">: [ # 出发日期 :Array </span><span style="color: #800000;">"</span><span style="color: #800000;">2020-01-22</span><span style="color: #800000;">"</span><span style="color: #000000;">, ], </span><span style="color: #800000;">'</span><span style="color: #800000;">stations</span><span style="color: #800000;">'</span><span style="color: #000000;">: { # 车站支持多个车站同时查询 :Dict or :List </span><span style="color: #800000;">'</span><span style="color: #800000;">left</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">北京</span><span style="color: #800000;">'</span><span style="color: #000000;">, </span><span style="color: #800000;">'</span><span style="color: #800000;">arrive</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">合肥</span><span style="color: #800000;">'</span><span style="color: #000000;">, }, </span><span style="color: #800000;">'</span><span style="color: #800000;">members</span><span style="color: #800000;">'</span>: [ # 乘客姓名,会根据当前账号自动识别乘客类型购买儿童票设置两个相同的姓名即可,程序会自动识别如 [<span style="color: #800000;">'</span><span style="color: #800000;">张三</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">张三</span><span style="color: #800000;">'</span><span style="color: #000000;">] </span><span style="color: #800000;">"</span><span style="color: #800000;">李雷</span><span style="color: #800000;">"</span><span style="color: #000000;">, </span><span style="color: #800000;">"</span><span style="color: #800000;">韩梅梅</span><span style="color: #800000;">"</span>#在姓名前加*<span style="color: #000000;">表示学生购买成人票 # </span><span style="color: #800080;">7</span>, # 支持通过序号确定唯一乘客,序号查看可通过 python main.py -t 登录成功之后在 runtime/user/<span style="color: #000000;"> 下找到对应的用户名_passengers.json 文件,找到对应的 code 填入 ], </span><span style="color: #800000;">'</span><span style="color: #800000;">allow_less_member</span><span style="color: #800000;">'</span>: <span style="color: #800080;">0</span><span style="color: #000000;">, # 是否允许余票不足时提交部分乘客 </span><span style="color: #800000;">'</span><span style="color: #800000;">seats</span><span style="color: #800000;">'</span><span style="color: #000000;">: [ # 筛选座位 有先后顺序 :Array # 可用值: 特等座, 商务座, 一等座, 二等座, 软卧, 硬卧, 动卧, 软座, 硬座, 无座 </span><span style="color: #800000;">'</span><span style="color: #800000;">二等座</span><span style="color: #800000;">'</span><span style="color: #000000;"> ], </span><span style="color: #800000;">'</span><span style="color: #800000;">train_numbers</span><span style="color: #800000;">'</span><span style="color: #000000;">: [ # 筛选车次可以为空,为空则所有车次都可以提交如 [] 注意大小写需要保持一致 </span><span style="color: #800000;">"</span><span style="color: #800000;">G267</span><span style="color: #800000;">"</span><span style="color: #000000;">, ], </span><span style="color: #800000;">'</span><span style="color: #800000;">except_train_numbers</span><span style="color: #800000;">'</span><span style="color: #000000;">: [ # 筛选车次,排除车次 train_numbers 和 except_train_numbers 不可同时存在 ], </span><span style="color: #800000;">'</span><span style="color: #800000;">period</span><span style="color: #800000;">'</span><span style="color: #000000;">: { # 筛选时间 </span><span style="color: #800000;">'</span><span style="color: #800000;">from</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">00:00</span><span style="color: #800000;">'</span><span style="color: #000000;">, </span><span style="color: #800000;">'</span><span style="color: #800000;">to</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">24:00</span><span style="color: #800000;">'</span><span style="color: #000000;"> } },</span> |
1 | <span style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px;"> 接着运行程序:<br /></span> |
1 | python3 main.py |
如果你不善于使用命令行模式,还可以使用图形界面观察抢票任务。
将配置中的 WEB_ENABLE 打开,启动程序后访问当前主机地址+端口号 (默认 8008) 即可,然后在浏览器中输入 http://127.0.0.1:8008。
现在,就可以让程序帮你抢票啦。
不过,抢票软件并非万能,巧 coder 难为无票之炊,除了技术,你可能还需要一点点运气。
无论采取哪种交通方式,祝大家都能开开心心过年回家,平平安安回来搬砖~
2020 已经开始,量子位也祝大家新年快乐^_^
传送门
testerSunshine/12306
https://github.com/testerSunshine/12306
py12306
https://github.com/pjialin/py12306
来自:
量子位(ID:QbitAI)