程序员码农的世界

Python抢票程序优化,可以选择车次和座次

2019-01-06  本文已影响10人  b4a0155c6514
Python抢票程序优化,可以选择车次和座次

阅读文本大概需要 5 分钟。

pk 哥在元旦前写了一篇关于自动化抢票的程序

用Python抢火车票加邮件通知,同时建了一个火车票助力群,本来只是写着玩玩,增加抢票的另一种途径而已。没想到短短几天,群里加了将近 150 名小伙伴,这也预示春节的火车票真是一票难求啊。

Python抢票程序优化,可以选择车次和座次

pk 哥写这个程序的初衷是因为去年我的返程票是通过手动不停的刷新点击抢到的,我想着能不能通过程序自动化去刷新并点击抢票,所以就有了这个 Python 抢票程序。

毕竟这个程序是 Python 模拟手工去操作浏览器的,所以会因为各种网络或者其他因素导致程序终止,群里反馈最多的就是增加车次选择功能和座次选择功能。本文主要讲解这两个优化点,群里也有很多小白也在用这个程序,所以本文会对一些详细的参数配置进行说明。

自动抢票流程

首先,梳理下本次优化后的抢票流程。

  1. 自动启动浏览器,自动化输入程序里设置好的 12306 的登录账号和密码。
  2. 自己手动输入验证码,图形验证码设别功能太复杂,涉及到人工智能的图像识别,自己做的话成功率不高,所以我这里让大家手动输入,输入验证码后手动点击「登录」按钮。
  3. 登录成功后页面会自动校验,确认登录成功后会自动跳转到查票页面。根据自己程序代码里输入的出发地和目的地进行查票。
  4. 根据自己输入的车次进行查询右边「预定」按钮是否高亮可点,不可点的话会一直点击「查询」按钮不断的刷新页面直到出现有票点击「按钮」按钮。
  5. 提交订单页面,选择乘客,选择座位类型,如果没有自己想要的类型,比如,二等座,页面会重新回到火车票查询页面,重新查询,如此循环。
  6. 抢到你想要的票后,提交订单,发送邮件,完成!

登录页面

这部分我把浏览器窗口最大化了,之前没设置全屏,大家电脑显示屏大小不一样,可能出现有些元素被遮挡无法点击。

登录之后可能会出现网络可能出现的问题的提示,估计是服务器的问题,这时手动点一下左上角的返回,一般就可以恢复正常,如果点一次还是这个提示,那就点两次吧。

Python抢票程序优化,可以选择车次和座次

查询页面

查询火车票页面,这个页面峰值时间时也会出现超时的提示,估计是访问的人数过多导致服务器异常导致的,有时候很快就能查到票,具体什么时候我也没找到规律。

Python抢票程序优化,可以选择车次和座次

这个我们也无法避免,程序会自动的帮我们刷新直到刷新出有票的页面,刷新频率:1 秒/次。

车次选择功能是大家比较关心的功能,之前是 order = 0 默认是全部车次,这次大家可以根据车次的位置输入相应的数字,比如要预定的车在第 5 行,你把 order = 5 就行,关于这些参数配置,下面会专门给大家列出来。

提交订单页面

提交订单页面程序会做两件事,第一个是根据你输入的乘客姓名进行选择,第二件事是根据是输入的座次进行判断,你想要的座次有票的话就会选择并提交订单,你想要的座次没票的话就会返回到上一级页面,重复查询车票,检查座次,如此循环,直到订到你想要的票。

Python抢票程序优化,可以选择车次和座次

邮件通知

邮件通知功能之前单独有写过一篇文章,大家如果不确定邮件通知功能是否有效的话可以单独把这部分源码拿出来,运行看看是否能发送成功,源码在公众号回复「邮件」获取,关于邮件通知的文章戳这里查看

Python抢票程序优化,可以选择车次和座次

30行Python代码实现自动收发邮件。

重要参数修改说明

重点来了,前面看不懂没关系,想直接拿源码运行的务必仔细看这里,拿到抢票源码后以下事项需要注意并配置。

Python 环境配置

本次程序我用的 Python 环境是 Python 3.6 的版本,其实 3.5 以上的应该都可以。官网上下载 Python3 的安装包,安装时记得勾选 Add Python 3.x to PATH 这个选项,勾选这个选项的好处是安装完成后它会自动帮你配置环境变量,不用像安装 Python2.x 时需要手动去配置。接下来都是傻瓜式安装,安装完成后终端下输入 Python 显示版本的话表示安装成功。还不会的话建议上网查查,网上教程很多。

Python抢票程序优化,可以选择车次和座次

pip 工具

pip 是通用的 Python 库管理工具,使用 pip 很方便的安装、管理库。第一步完成后这个 pip 工具是自带的,你可以在终端下输入 pip list 命令查看你当前安装的所有 Python 库。

Python抢票程序优化,可以选择车次和座次

安装导入相应的库

本程序主要用到的库是 splinter,主要用这个库来驱动浏览器进行操作页面的,用 pip 命令直接安装。

<pre style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">pip install splinter
</pre>

Splinter 相关的教程中文文档地址如下,如有兴趣的话可以学习一下。

<pre style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">https://splinter-docs-zh-cn.readthedocs.io/zh/latest/tutorial.html
</pre>

安装完成后在 IDE 中用 import 导入这个库,如果还不能用的话记得在编辑器中安装引入一下,我用的是 Pycharm 编辑器,在设置中引入安装,见下图。

Python抢票程序优化,可以选择车次和座次

Python 发送邮件需要用到 Python 自带的两个模块,smtplib 和 email。直接 import 导入,无需下载。

所以,真正需要安装的只有 splinter 库,其他直接导入就可用,在编辑器中导入。

<pre style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">from splinter.browser import Browser
from time import sleep
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
from email.header import Header
</pre>

浏览器驱动下载并指定路径

这个问题大家也出现比较多,为什么要下载浏览器驱动呢?因为 splinter 库的底层原理是通过 WebDriver 去驱动浏览器做相应的操作的,所以使用对应的浏览器必须要下载对应的浏览器驱动。我用的是 chrome 浏览器,所以我下载的是 chromedriver,这里还有个坑,chromedriver 和 chrome 浏览器有映射关系,你必须下载对应的版本。映射关系如下,大家先查看你的 chrome 浏览器版本,再下载对应的 chromedriver,chromedriver 下载地址点击「阅读原文」可查看。(左右滑动查看全部)

<pre style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">ChromeDriver v2.43 (2018-10-16)----------Supports Chrome v69-71
ChromeDriver v2.42 (2018-09-13)----------Supports Chrome v68-70
ChromeDriver v2.41 (2018-07-27)----------Supports Chrome v67-69
ChromeDriver v2.40 (2018-06-07)----------Supports Chrome v66-68
ChromeDriver v2.39 (2018-05-30)----------Supports Chrome v66-68
ChromeDriver v2.38 (2018-04-17)----------Supports Chrome v65-67
ChromeDriver v2.37 (2018-03-16)----------Supports Chrome v64-66
ChromeDriver v2.36 (2018-03-02)----------Supports Chrome v63-65
ChromeDriver v2.35 (2018-01-10)----------Supports Chrome v62-64
</pre>

(Chrome 和ChromeDriver 映射表)

chromedriver 下载解压完成后把他的路径复制下来,替换源码 33 行中的路径。

Python抢票程序优化,可以选择车次和座次

邮件通知功能设置

上面安装了对应的库后,需要填写的信息如下:发件人和收件人邮箱、发件人的授权码。所以需要修改的位置是 sendMail 函数中的 51 行和 52 行的发件人邮箱账号和收件人邮箱账号,61 行的发件人邮箱的授权码。

Python抢票程序优化,可以选择车次和座次

授权码获取方法参考文章

Python抢票程序优化,可以选择车次和座次

30行Python代码实现自动收发邮件,我用的发邮件的邮箱是我的小号 QQ 邮箱,收件人邮箱是我的大号 QQ邮箱。我试了下,QQ 邮箱里发件人和收件人可以是一样的,也就是可以自己给自己发邮件,大家自行选择,建议先独立把发邮件的代码运行下,查看是否发送成功,一般运行失败就是因为授权码不对造成的,重新获取一次授权码好了。公众号回复「邮件」获取发邮件功能的源码。

座次对应的数值

经过调试查看,不同的座次对应的 value 值不一样。

Python抢票程序优化,可以选择车次和座次

多次调试之后,我把不同座次对应的 value 值整理成了表格。

Python抢票程序优化,可以选择车次和座次

代码修改位置在源码 112 行和 113 两行,两行都要改动,改动成你想要的座次对应的 value 就行。

12306 用户名和 12306 登录密码

这两项在 main 函数中修改成自己的就行,把源码 114 和 145 行修改成自己的即可。

车次选择

车次用了 order 字段来表示,

0 代表所有车次,1 表示第一行的车次,2 表示第二行的车次,以此类推。一般你输入出发点和目的地后,所有的车次位置是固定的,你输入你想订的车次的位置数字即可。源码修改位置也是在 main 函数里,第 146 行。

乘客名格式

乘客名,比如 passengers = ['XXX', 'XXX'],支持多选,注意下学生票需注明,注明方式为:passengers = ['XXX(学生)', 'XXX'],不然会报错,源码修改位置也是在 main 函数里,第 149 行。

乘车日期格式

乘车日期,格式为:'2019-01-28',源码修改位置也是在 main 函数里,第 151 行。

出发地和目的地 cookie 获取

这个由于时间问题,没有优化,目前只能手动去查找获取出发地和目的地,打开自己的 12306 查询火车票页面,输入出发地和目的地。将页面的调试模式打开,用快捷键 F12 或者鼠标右键「检查」打开调试模式,选择 Network,点击「查询」按钮,这样就能获取对应出发地和目的地的 cookie。源码修改位置也是在 main 函数里,第 153 行和 155 行。

Python抢票程序优化,可以选择车次和座次

总结下,以上需要修改的地方,chromedriver 路径:在初始化函数 init 里面、邮件通知功能收发邮箱账号和发件人授权码在 sendMail 函数中修改、修改对应座次 value 值在 check_ticket 函数中修改、其他信息包括:12306用户名、12306密码、车次选择、乘客名、乘车日期、出发日期、出发地和目的地 cookie 值,都在源码最下方的 main 函数中修改。

Python抢票程序优化,可以选择车次和座次

重要说明:本程序由于时间有限,配置项也挺多的,但是为了抢到票,我们只能多尝试一种方法了,本程序是模拟人工操作浏览器,还是会存在很多问题的,比如说由于网络关系导致页面长时间停留从而找不到元素而程序停止,其他各种预想不到的问题也会出现,程序停止的话也只能重启下程序继续抢,后期大家需要的话我也会慢慢优化。欢迎大家在抢票群里一起优化讨论,毕竟我也要工作,个人时间有限。大家也不要把它当做唯一的抢票工具,我们还是要把其他的抢票工具一起用起来,所以我建火车票助理群的目的也是为了让大家有更多的途径抢到票,回家过年,大家相互点点助力,这样抢到额概率更大一下。

上一篇下一篇

猜你喜欢

热点阅读