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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liyuefeilong/article/details/50428607

有一段时间没有使用Python了,前几天经朋友提起一篇关于用Python实现抢火车票的文章,百度了实现抢火车票的技术细节,网上却有不少资料,也不是新鲜的东西。在了解了一些技术手段,阅读了一些大神的博文后,也尝试实现了一下,代码写得粗糙,纯当娱乐,本文在Windows系统下完成。需要提到的是,抢票过程中的验证码部分只能手动完成。

首先,我需要的工具和组件有:

  • Chrome浏览器
  • 浏览器驱动ChromeDriver
  • Python 3.5
  • Web应用测试工具Splinter

Chrome浏览器可自行下载,其浏览器驱动ChromeDriver可在以下链接找到:http://chromedriver.storage.googleapis.com/index.html?path=2.20/

这里写图片描述

在官网下载Python,选择Windows x86 executable installer,安装过程中会一同安装IDLE、pip等等,可勾选选项添加Python为环境变量(在Windows cmd下运行Python,需要设置环境变量)。安装完成后,执行:pip install splinter安装Splinter即可。

这里写图片描述

基本的配置已完成,测试一下,cmd下运行Python,分别键入以下指令:

>>> from splinter.browser import Browser
>>> b = Browser(driver_name="chrome")
>>> b.visit("http://www.qq.com")

这里写图片描述

可以创建一个基本文件,写入以上三句语句:

这里写图片描述

在执行后续操作时,需要用到Google Chrome开发者工具,按“F12”或“shift+ctrl+i”呼出。找到Elements选项卡,这里记录了当前页面每个元素的信息,如以下的搜索栏和“百度一下”按键,可选择想要查看的网页要素或位置,Elements会跳转到相应的实现代码。

这里写图片描述

这里写图片描述

搜索栏的name = “wd”,”百度一下“按键的id = “su”,在得到这一信息后,可以执行以下三步操作:
1. 输入:b.fill("wd", "splinter")即可在搜索栏搜索splinter。
2. 输入:button = b.find_by_value(u"百度一下")寻找该按键
3. 输入:button.click() 点击该按键

更多操作,可参考splinter的官方文档。。。

下面开始进入12306的网址进行操作:

这里写图片描述

类似于在百度页面的操作,在用户名和密码栏目中输入个人信息:

b.find_by_text(u"登录").click()
b.fill("loginUserDTO.user_name",username) # username部分输入自己的账号
b.fill("userDTO.password",passwd) # passwd部分输入账号密码

这里写图片描述

之所以说是半自动抢票,是因为在抢票之前需要手动搜集一些信息,比如手动选择一次出发地点、日期和到达地点等信息,然后F12打开开发者工具,点击Resources,找到cookies选项,可以看到下图所示的内容:

这里写图片描述

通过cookies可以看到手动选择的出发地点_jc_save_fromStation及其值value,还有出发日期_jc_save_fromData及目的地_jc_save_toStation等内容。其中每个地名会对应一个独占的value,因此如果你是要刷从北京去上海的车票,需要手动先查查北京和上海分别对应的value值,并记录下来,后面有用。

接下来,执行以下指令,添加cookies信息:

b.cookies.add({"_jc_save_fromDate":"2016-01-18"}) # 此处添加出发日期
b.cookies.add({"_jc_save_fromStation":"此处添加各地名所对应的value值"}) # 此处添加出发地
b.cookies.add({u'_jc_save_toStation':'此处添加各地名所对应的value值'}) # 此处添加目的地

这里写图片描述

之后,再次刷新页面时,可以发现浏览器会自动填写之前手动填写的内容,在执行刷票时,这无疑节省了很多时间:

这里写图片描述

后续的操作也不多了,reload页面,然后寻找页面内的”查询“按钮并点击,再寻找可点击的”预订“按钮,这里有一个问题是可能出现多个班次,因此如果要操作代码去点击某个班次的”预订“按钮,也不困难,使用以下指令即可:

b.find_by_text(u"查询").click()
b.find_by_text(u"预订")[1].click() # 下标1表示买的是可选班次的第二班车

这里写图片描述

最后执行几句指令自动选取购票人,然后再手动选取验证码图片,即可完成抢票(验证码还是一道不可逾越的鸿沟)。

以上是整个流程,在完整代码中,只需再加入一些基本的循环和判断,所有这些加起来不到100行。整个过程手动输入验证码是不可避免的,除非拥有验证码的数据库,然后在这基础上做一些图像识别的算法,但这会是一个工作量较大的任务。

参考链接:http://www.jb51.net/article/75992.htm

展开阅读全文

没有更多推荐了,返回首页