python+splinter实现12306网站刷票并自动购票流程
作者:kun_dl 发布时间:2023-08-02 20:50:18
标签:python,splinter,刷票
通过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()
来源:https://blog.csdn.net/kun_dl/article/details/81031442


猜你喜欢
- (一) 常用的CSS命名规则:头:header内容:content/container尾:footer导航:nav侧栏:sidebar栏目:
- 本文介绍了关于redux-saga中take使用方法详解,分享给大家,具体如下:带来一个自己研究好久的API使用方法.redux-saga中
- 一、前言最近经常碰到开发误删除误更新数据,这不,他们又给我找了个麻烦,我们来看下整个过程。二、过程由于开发需要在生产环节中修复数据,需要执行
- 微博如火如荼,大家都选择用微博带来社会化流量,顺便推广产品和网站,几乎所有的网站都有分享到代码,但是还有一种更快捷的分享方式,javascr
- 前言首先明确一点这个错误只会发生在delete语句或者update语句,拿update来举例 : update A表 set A列 = (s
- 我就废话不多说了,大家还是直接看代码吧~from docx import Documentfrom docx import RTimport
- 训练模型时,我们并不是直接将图像送入模型,而是先将图像转换为tfrecord文件,再将tfrecord文件送入模型。为进一步理解tfreco
- 1、引言小 * 丝:鱼哥,你说这就快到圣诞节了,我应该送女神什么礼物呢?小鱼:你的女神又不缺什么礼物,倒不如送点惊喜?小 * 丝:送什么惊喜呢?小鱼
- 本文实例讲述了Python基于动态规划算法计算单词距离。分享给大家供大家参考。具体如下:#!/usr/bin/env python#codi
- 前几天和一个小伙伴交流了一下nodejs中epoll和处理请求的一些知识,今天简单来聊一下nodejs处理请求的逻辑。我们从listen函数
- OpenCV简介OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Ma
- 我目标文件夹下有一大批图片,我要把它转变为指定尺寸大小的图片,用pthon和opencv实现的。以上为原图片。import cv2impor
- 前言虽然一直在说“去IOE化”,但是在国企和政府,Oracle的历史包袱实在太重了,甚至很多业务逻辑都是写在Oracle的各种存储过程里面实
- 1 引言在python内存管理中,有一个block的概念。它比较类似于SGI次级空间配置器。首先申请一块大的空间(4KB),然后把它切割成一
- 数据库和操作系统一样,是一个多用户使用的共享资源。当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操
- 前言正则表达式是什么应该不用过多介绍,每位程序员应该都知道,正则表达式描述的是一种规则,符合这种限定规则的字符串我们认为它某种满足条件的,是
- 前言当后台返回的数据过多时,我们就要配置分页器,比如一页最多只能展示10条等等,drf中默认配置了3个分页面PageNumberPagina
- 本文实例讲述了Python基于PyGraphics包实现图片截取功能的方法。分享给大家供大家参考,具体如下:先安安装PyGraphics包
- pytorch加载图片数据集有两种方法。1.ImageFolder 适合于分类数据集,并且每一个类别的图片在同一个文件夹, ImageFol
- 前文主要纠正title用法上的几点误区,其实除链接和表单的常规标签用法。在内容组织方面还有大潜力待发掘,比如写网志经常会有针对词、短语说明的