python+splinter实现12306网站刷票并自动购票流程


Posted in Python onSeptember 25, 2018

通过python+splinter,实现在12306网站刷票并自动购票流程(无法自动识别验证码)。

此类程序只是提高了12306网站的 <查询> 刷新频率(默认自动查询的刷新频率为5秒)。对于学习splinter感觉还是不错的,但是想通过装个类似刷票程序成功购票的 还是多花点钱升级升级硬件设备,提高提高网速吧。

程序写的有点乱,随时修改ing。

#!/usr/bin/env python3
# encoding: utf-8
 
from splinter.browser import Browser
import time
 
#12306的账号,密码
user_name = 'xxxxxxxxxx' #自行修改
pass_word = 'xxxxxxxxxx'
 
# 通过splinter,登录12306网站(登录验证码需要手动验证)
b = Browser(driver_name = 'firefox') # 设置火狐浏览器
b.visit('https://kyfw.12306.cn/otn/leftTicket/init') # 打开12306界面
b.find_by_id(u'login_user') # 点击登录按钮
 
b.fill('loginUserDTO.user_name',user_name) # 填写账号
b.fill('userDTO.password',pass_word) # 填写密码
 
# 手动填写验证码并登录,登录成功后等待自动跳转到购票页面。
'''
跳转页面过程中:
程序可能会报错:[WinError 10053] 您的主机中的软件中止了一个已建立的连接。
原因:未知
解决办法:写一个循环,程序不停的尝试链接跳转页面(总会成功),成功后跳出循环。
'''
while True:
  if b.url == 'https://kyfw.12306.cn/otn/index/initMy12306': # 判断是否登录成功
    try:
      b.visit('https://kyfw.12306.cn/otn/leftTicket/init') # 访问购票页面
    except ConnectionAbortedError: #捕捉可能出现的异常,继续访问
      b.visit('https://kyfw.12306.cn/otn/leftTicket/init') 
    if b.url == 'https://kyfw.12306.cn/otn/leftTicket/init': # 判断是否跳转购票页面成功
      break
 
# 添加、加载cookies信息,查询余票。(自动添加出发地、目的地、日期,例如:北京-郑州)
b.cookies.add({'_jc_save_fromDate':'2018-08-11'}) # 出发日期
b.cookies.add({'_jc_save_fromStation':u'%u5317%u4EAC%2CBJP'}) # 出发站信息(北京)
b.cookies.add({'_jc_save_toDate':'2018-08-11'}) # 到达日期
b.cookies.add({'_jc_save_toStation':u'%u90D1%u5DDE%2CZZF'}) # 目的地信息(郑州)
b.reload() # 重新加载cookies
b.find_by_text(u'查询').click() #点击查询
 
# 添加车次类型
l = ['GC-高铁/城际','D-动车','Z-直达','T-特快','K-快速','其他']#在列表里可以去掉不需要的车次类型
for i in l:
  btn = b.find_by_text(i)
  btn.click()
  
# 下拉订票帮手(此步骤可跳过)  
b.find_by_id(u'show_more').click()
 
 
# 设置坐席
def The_seat():
 
  '''
  添加坐席后,网站会自动勾选<自动提交>、<自动查询>功能。
  <自动查询> 默认的是5秒刷新一次(慢),所以我们要关闭此选项,提高刷新频率。
  '''
  seat =['二等座','软卧','硬卧','硬座','无座'] #设置一个坐席列表
  b.find_by_xpath('/html/body/div[6]/div[5]/div[2]/div[7]/div[2]/span/a').click()#打开坐席选择的菜单窗口
  for i in seat:
    b.find_by_name(i).click() #添加坐席
  b.find_by_xpath('/html/body/div[11]/div[1]/a').click()#关闭弹窗
  b.find_by_text(u'开启自动查询').click()# 点击关闭<自动查询>选项(慢)。关闭自动查询功能后,自动提交功能也会关闭。
 
 
# 购票 
def Train_ticket_purchase():
  
  The_seat() #设置坐席
  b.find_by_id(u'show_more').click() # 关闭订票帮手(此步骤可跳过)
 
  #查询订票
  while b.url != 'https://kyfw.12306.cn/otn/confirmPassenger/initDc': #以预订成功跳转页面为判断条件
    try:
      b.find_by_text(u'查询').click() # 点击查询
      if b.is_element_present_by_text(u'预订') == True: #判断是否有<预订>
        for i in b.find_by_text(u'预订'): # b.fin_by_text(u'预订'),返回包含<预订>元素的列表,其中有些可以点击‘预订'购票,有些‘预订'显灰色无票状态,无法点击预订购票的。
          if i.has_class('btn72'): #筛选<预订>元素,区分可以点击预订的和不可以点击的(可以点击<预订>的元素,都包含属性class('btn72'))
            i.click()#点击预订购票
          
            if b.is_element_present_by_xpath('//*[@id="content_defaultwarningAlert_hearder"]') == True: #可能会弹窗提示:当前时间不可预订
              b.find_by_xpath('//*[@id="gb_closeDefaultWarningWindowDialog_id"]').click() # 关闭提示弹窗
              print('当前时间不可预订,请关闭程序稍后再运行。')
              break
 
            if b.is_element_present_by_xpath('//*[@id="content_defaultwarningAlert_title"]') == True: #可能会弹窗提示:您选择的列车距开车时间很近了,请确保有足够的时间抵达车站,并办理换取纸质车票、安全检查、实名制验证及检票等手续,以免耽误您的旅行。
              b.find_by_xpath('//*[@id="qd_closeDefaultWarningWindowDialog_id"]').click() #关闭弹窗(注意:关闭弹窗,但是仍然会购票)
            
            b.find_by_text(u'xxx')[1].click() #自行添加乘车人名字(注意:登录账号本人的名字元素可能会有两个(一个账号,一个乘车人),注意区分开)
            b.find_by_text(u'提交订单').click()
 
            #确认订单(不知道为什么 b.find_by_xpath()方法不行。。。。)
            b.find_by_css('html body#body_id.dhtmlx_winviewport.dhtmlx_skin_dhx_terrace div.dhtmlx_window_active div.dhtmlx_wins_body_outer div.dhtmlx_wins_body_inner.dhtmlx_wins_no_header div div#checkticketinfo_id div#content_checkticketinfo_id.up-box.w664 div.up-box-bd.ticket-check div#confirmDiv.lay-btn a#qr_submit_id.btn92s').click()
            print('预订成功,退出程序')
            break
          else:
            print('暂时没票,继续查询中...')
      else:
        print('暂时没票,继续查询中...')      
    except:
      print('不可预订,请稍后再次运行程序...')
      break
 
 
if __name__ == '__main__':
  Train_ticket_purchase()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python使用xauth方式登录饭否网然后发消息
Apr 11 Python
Python实现删除文件但保留指定文件
Jun 21 Python
python中PIL安装简单教程
Apr 21 Python
深入解析Python中的descriptor描述器的作用及用法
Jun 27 Python
Python遍历目录并批量更换文件名和目录名的方法
Sep 19 Python
python中import reload __import__的区别详解
Oct 16 Python
Python之web模板应用
Dec 26 Python
Python编程实现线性回归和批量梯度下降法代码实例
Jan 04 Python
Python3.5实现的罗马数字转换成整数功能示例
Feb 25 Python
500行Python代码打造刷脸考勤系统
Jun 03 Python
TensorFlow 多元函数的极值实例
Feb 10 Python
Python连接Mysql进行增删改查的示例代码
Aug 03 Python
基于Python3.6+splinter实现自动抢火车票
Sep 25 #Python
Python做智能家居温湿度报警系统
Sep 25 #Python
python+splinter自动刷新抢票功能
Sep 25 #Python
python+Splinter实现12306抢票功能
Sep 25 #Python
一百多行python代码实现抢票助手
Sep 25 #Python
python爬虫之自动登录与验证码识别
Jun 15 #Python
python使用matplotlib模块绘制多条折线图、散点图
Apr 26 #Python
You might like
复杂检索数据并分页显示的处理方法
2006/10/09 PHP
深入PHP购物车模块功能分析(函数讲解,附源码)
2013/06/25 PHP
PHP文件上传判断file是否己选择上传文件的方法
2014/11/10 PHP
ThinkPHP中公共函数路径和配置项路径的映射分析
2014/11/22 PHP
ThinkPHP自定义函数解决模板标签加减运算的方法
2015/07/03 PHP
PHP children()函数讲解
2019/02/03 PHP
半角全角相互转换的js函数
2009/10/16 Javascript
Javascript倒计时代码
2010/08/12 Javascript
jquery下拉select控件操作方法分享(jquery操作select)
2014/03/25 Javascript
使用jquery实现放大镜效果
2014/09/02 Javascript
js给网页加上背景音乐及选择音效的方法
2015/03/03 Javascript
PHP+jQuery实现随意拖动层并即时保存拖动位置
2015/04/30 Javascript
kindeditor编辑器点中图片滚动条往上顶的bug
2015/07/05 Javascript
js实现继承的5种方式
2015/12/01 Javascript
jquery日历插件datepicker用法分析
2016/01/22 Javascript
JS防止网页被嵌入iframe框架的方法分析
2016/09/13 Javascript
AngularJS开发教程之控制器之间的通信方法分析
2016/12/25 Javascript
详解微信小程序 template添加绑定事件
2017/06/23 Javascript
jquery分页插件pagination使用教程
2018/10/23 jQuery
如何解决.vue文件url引用文件的问题
2019/01/18 Javascript
Node.js系列之连接DB的方法(3)
2019/08/30 Javascript
解决React在安装antd之后出现的Can't resolve './locale'问题(推荐)
2020/05/03 Javascript
JavaScript中的各种宽高属性的实现
2020/05/08 Javascript
[10:39]DOTA2上海特级锦标赛音乐会纪录片
2016/03/21 DOTA
[04:44]DOTA2西游记战队视频彩蛋流出 师徒开黑巧遇林书豪
2016/08/03 DOTA
在SAE上部署Python的Django框架的一些问题汇总
2015/05/30 Python
对python中的pop函数和append函数详解
2018/05/04 Python
python写入并获取剪切板内容的实例
2018/05/31 Python
python 检查是否为中文字符串的方法
2018/12/28 Python
基于Python获取城市近7天天气预报
2019/11/26 Python
Django 实现对已存在的model进行更改
2020/03/28 Python
计算机应用专业应届毕业生中文求职信范文
2013/11/29 职场文书
教育科研先进个人材料
2014/01/26 职场文书
小学生手册家长评语
2014/04/16 职场文书
2015年党员承诺书
2015/01/21 职场文书
2016年离婚协议书范文
2016/03/18 职场文书