python实现火车票查询订票退票_使用Python和Splinter实现12306火车票查询与抢票

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

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

Chrome浏览器

浏览器驱动ChromeDriver

Python 3.5

Web应用测试工具Splinter

在官网下载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行。整个过程手动输入验证码是不可避免的,除非拥有验证码的数据库,然后在这基础上做一些图像识别的算法,但这会是一个工作量较大的任务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#这只是一个半成品,只是实现了,一个完整的订票过程,对于,如果刷票,自己研究 #简单过程 # 第一、getRandAndCookie() 获得cook 和一个随机数用于登录 # 第二、getEnterRandCode() 得到登录时的识别码 # 第三、setuseandpassword(randcode,use,password) 发送随机数、识别码和用户及密码。由于随机数只在内部使用,所以定义成了全局变量, # 第四、GetTrainList() 得到所有车站列表,'@bjb|北京北|VAP|beijingbei|bjb|0' 其中有中文、拼音、拼音缩写、所一个ID(唯一),其主要是可以,通过上面的列表,找到它的唯一ID,TranCityToId('南昌') # 第五、GetTrainNumList(date,fromstationid,tostationid,starttime) 得到哪到哪的所在车次,消息格式如下,其中所以,一下车次的的ID:"id":"650000K1060I" # {"end_station_name":"北京西","end_time":"16:18","id":"650000K1060I","start_station_name":"深圳","start_time":"10:54","value":"K106"} # 通过ChangeToTrainNumId('K106')得到车次ID # 第六、QueryTrain(fromstationid,tostationid,date,stationNum,starttime) 就是点击查询按键,得到是否有能预订,格式如下 #       南昌         20:12,    北京西        07:38,11:26,--,--,--,--,10,有,有,--,有,有,--,<a name='btn130_2' class='btn130_2' # 通过choiceSubmitNum(stationNum,trainsubmitinfo)提取出getSelected()消息 # 第七、submitRequest(choiceSubmitNum(stationNum,trainsubmitinfo),date,starttime) 就是点击预订按钮 # 第八、getrandCheckCode()得到提交订单的识别码 # 第十、CheckInMyTicket(info,randcode,peoples)点击提交,如果成功的话,就会返回{"errMsg":"Y"} # 出于,网络是UTF8格式,所以,必须# -*- coding: utf-8 -*-,(当然,自己转换也是可以的) # 出于这一个控制台信息,所以,识别码的图片在脚本同一目录 #得到头信息

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值