12306抢票脚本
本脚本使用一个类来实现所有代码,大体上分为以下几个模块及其步骤:
初始化对象属性(在抢票前进行的属性初始化,包括初始化浏览器模拟对象,个人信息等)。 建立模拟浏览器,模拟浏览器进行cookie等存储。 验证模块: 获取验证图片到本地 将8个图片坐标位置改装成易于输入的1—8的位置编号,输入对应的位置号 发送请求进行后台校验 登录模块: 输入账号密码,请求服务器 获取apptk授权码 授权通过,成功获取用户信息,将授权信息存储到cookie 获取站点模块: 获取余票信息模块: 输入起始站点与乘车时间,请求服务器,查询余票信息 将余票信息进行格式化输出 选择相应车次 订单模块: 注入起始点、日期,车次码信息,提交请求,返回状态信息 获取该车次的详细信息,选择车票类型 获取所有已添加乘客 选择乘车乘客 检查订单信息 确认订单信息,占座成功,下单完成 发送邮件,短信,提醒支付
以下贴出所有源码,仅供参考,其中发送邮件与发送短信模块所需的参数须自行到相关网站获取。
from urllib import request
from json import loads
from prettytable import PrettyTable
from colorama import init, Fore, Back, Style
from email. mime. text import MIMEText
from qcloudsms_py import SmsSingleSender
from qcloudsms_py. httpclient import HTTPError
import urllib. parse as parse
import http. cookiejar as cookiejar
import re
import time
import smtplib
init( autoreset= False )
class Colored ( object ) : def red ( self, s) : return Fore. LIGHTRED_EX + s + Fore. RESETdef green ( self, s) : return Fore. LIGHTGREEN_EX + s + Fore. RESETdef yellow ( self, s) : return Fore. LIGHTYELLOW_EX + s + Fore. RESETdef white ( self, s) : return Fore. LIGHTWHITE_EX + s + Fore. RESETdef blue ( self, s) : return Fore. LIGHTBLUE_EX + s + Fore. RESETclass train_ticket_purchase ( ) : """初始化对象属性""" def __init__ ( self) : self. headers = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' } self. opener = self. __get_opener( ) self. username = "" self. phone_number = "13781206061" self. receive_email = "wsyjlly@foxmail.com" self. seatType = "1" self. seat_types_code = [ "M" , "0" , "1" , "N" , "2" , "3" , "4" , "F" , "6" , "9" ] self. ticketType = "1" self. query_seats_count = 1 self. passengers_name = "" self. seat_list = [ "yz_num" , "wz_num" , "rz_num" , "yw_num" , "rw_num" , "dw_num" , "gr_num" , "ze_num" , "zy_num" , "swz_num" ] self. ticketTypes = { "1" : "成人票" , "2" : "儿童票" , "3" : "学生票" , "4" : "残军票" } self. seatTypes = { "M" : "一等座" , "0" : "二等座" , "1" : "硬座" , "N" : "无座" , "2" : "软座" , "3" : "硬卧" , "4" : "软卧" , "F" : "动卧" , "6" : "高等软卧" , "9" : "商务座" } self. seat_dict = { "yz_num" : "硬座" , "wz_num" : "无座" , "rz_num" : "软座" , "yw_num" : "硬卧" , "rw_num" : "软卧" , "dw_num" : "动卧" , "gr_num" : "高级软卧" , "ze_num" : "二等座" , "zy_num" : "一等座" , "swz_num" : "商务特等座" } """建立模拟浏览器,模拟浏览器进行cookie存储""" def __get_opener ( self) : c = cookiejar. LWPCookieJar( ) cookie = request. HTTPCookieProcessor( c) opener = request. build_opener( cookie) request. install_opener( opener) return opener"""验证模块:1、获取验证图片到本地2、将8个图片坐标位置改装成易于输入的1—8的位置编号,输入对应的位置号3、发送请求进行后台校验""" def get_image ( self) : req_catch_image = request. Request( 'https://kyfw.12306.cn/passport/captcha/captcha-image' ) req_catch_image. headers = self. headerscode_file = self. opener. open ( req_catch_image) . read( ) with open ( '/code.jpg' , 'wb' ) as f: f. write( code_file) def verify ( self) : answer = { "1" : "40,40" , "2" : "110,40" , "3" : "180,40" , "4" : "260,40" , "5" : "40,120" , "6" : "110,120" , "7" : "180,120" , "8" : "260,120" , } print ( "+----------+----------+----------+----------+" ) print ( "| 1 | 2 | 3 | 4 |" ) print ( "|----------|----------|----------|----------|" ) print ( "| 5 | 6 | 7 | 8 |" ) print ( "+----------+----------+----------+----------+" ) input_code = input ( "请在1—8中选择输入验证图片编号,以半角','隔开。(例如:1,3,5):" ) answer_code = "" try : for i in input_code. split( "," ) : answer_code += ( "," + answer[ i] ) if ( i is not input_code[ 0 ] ) else answer[ i] except : print ( "输入有误,请重新输入!" ) self. verify( ) req_check = request. Request( 'https://kyfw.12306.cn/passport/captcha/captcha-check' ) req_check. headers = self. headersdata = { 'answer' : answer_code, 'login_site' : 'E' , 'rand' : 'sjrand' } data = parse. urlencode( data) . encode( ) check_result = self. opener. open ( req_check, data= data) . read( ) . decode( ) return loads( check_result) def sys_verify ( self) : self. get_image( ) verify_result = self. verify( ) while verify_result[ 'result_code' ] is not '4' : print ( '验证失败,已重新下载图片,请重新验证!' ) self. get_image( ) verify_result = self. verify( ) print ( "验证通过!" ) return """登录模块:1、输入账号密码,请求服务器2、获取apptk授权码3、授权通过,成功获取用户信息,将授权信息存储到cookie""" def login ( self) : req_login = request. Request( 'https://kyfw.12306.cn/passport/web/login' ) req_login. headers = self. headersname = input ( "请输入12306帐号:" ) pwd = input ( "请输入密码:" ) data = { 'username' : name, 'password' : pwd, 'appid' : 'otn' } data = parse. urlencode( data) . encode( ) login_result = self. opener. open ( req_login, data= data) . read( ) . decode( ) return loads( login_result) def get_tk ( self) : req = request. Request( 'https://kyfw.12306.cn/passport/web/auth/uamtk' ) req. headers = self. headersdata = { "appid" : "otn" } data = parse. urlencode( data) . encode( ) result = self. opener. open ( req, data= data) . read( ) . decode( ) return loads( result) def auth ( self, newapptk) : req = request. Request( 'https://kyfw.12306.cn/otn/uamauthclient' ) req. headers = self. headersdata = { "tk" : newapptk} data = parse. urlencode( data) . encode( ) result = self. opener. open ( req, data= data) . read( ) . decode( ) return loads( result) def sys_login ( self) : self. login( ) result = self. get_tk( ) try : result = self. auth( result[ 'newapptk' ] ) except : print ( "登录失败,账号或密码错误!" ) self. sys_verify( ) self. sys_login( ) self. username = result[ "username" ] print ( "欢迎用户" , result[ "username" ] , "您已登录成功!" ) if result[ "result_code" ] == 0 else print ( result[ "result_message" ] ) return """获取站点模块:获取所有站点名称与站点码""" def __get_city_result ( self) : req_city_code = request. Request( 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9093' ) req_city_code. headers = self. headersresult = self. opener. open ( req_city_code) . read( ) . decode( ) return resultdef get_city_code ( self, name) : result = self. __get_city_result( ) start = result. index( name) + len ( name) result = result[ start+ 1 : start+ 4 ] return resultdef get_station_names ( self) : result = self. __get_city_result( ) stations = re. findall( r'([\u4e00-\u9fa5]+)\|([A-Z]+)' , result) station_codes = dict ( stations) station_names = dict ( zip ( station_codes. values( ) , station_codes. keys( ) ) ) return station_names"""获取余票信息模块:1、输入起始站点与乘车时间,请求服务器,查询余票信息2、将余票信息进行格式化输出3、选择相应车次""" def get_tickets ( self, from_station, to_station, train_date) : url = 'https://kyfw.12306.cn/otn/leftTicket/queryX?' data = { "leftTicketDTO.train_date" : train_date, "leftTicketDTO.from_station" : from_station, "leftTicketDTO.to_station" : to_station, "purpose_codes" : "ADULT" } req = request. Request( url + parse. urlencode( data) ) req. headers = self. headersresult = self. opener. open ( req) . read( ) . decode( ) return loads( result) def get_ticket_format ( self, from_station_name, from_station, to_station_name, to_station, train_date) : print ( '为您查询到从' , from_station_name, '到' , to_station_name, '的余票信息如下:' ) result = self. get_tickets( from_station, to_station, train_date) result_list = result[ 'data' ] [ 'result' ] station_names = self. get_station_names( ) table = PrettyTable( [ "车次" , "出发/到达车站" , "出发/到达时间" , "历时" , "商务座" , "一等座" , "二等座" , "高级软卧" , "软卧" , "动卧" , "硬卧" , "软座" , "硬座" , "无座" , "其他" , "备注" ] ) for item in result_list: name = [ "station_train_code" , "from_station_name" , 'start_time' , "lishi" , "swz_num" , "zy_num" , "ze_num" , "gr_num" , "rw_num" , "dw_num" , "yw_num" , "rz_num" , "yz_num" , "wz_num" , "qt_num" , "note_num" ] data = { "station_train_code" : '' , "from_station_name" : '' , "to_station_name" : '' , 'start_time' : '' , 'end' : '' , "lishi" : '' , "swz_num" : '' , "zy_num" : '' , "ze_num" : '' , "dw_num" : '' , "gr_num" : '' , "rw_num" : '' , "yw_num" : '' , "rz_num" : '' , "yz_num" : '' , "wz_num" : '' , "qt_num" : '' , "note_num" : '' } item = item. split( '|' ) data[ 'station_train_code' ] = item[ 3 ] data[ 'from_station_name' ] = item[ 6 ] data[ 'to_station_name' ] = item[ 7 ] data[ 'start_time' ] = item[ 8 ] data[ 'arrive_time' ] = item[ 9 ] data[ 'lishi' ] = item[ 10 ] data[ 'swz_num' ] = item[ 32 ] or item[ 25 ] data[ 'zy_num' ] = item[ 31 ] data[ 'ze_num' ] = item[ 30 ] data[ 'gr_num' ] = item[ 21 ] data[ 'rw_num' ] = item[ 23 ] data[ 'dw_num' ] = item[ 27 ] data[ 'yw_num' ] = item[ 28 ] data[ 'rz_num' ] = item[ 24 ] data[ 'yz_num' ] = item[ 29 ] data[ 'wz_num' ] = item[ 26 ] data[ 'qt_num' ] = item[ 22 ] data[ 'note_num' ] = item[ 1 ] color = Colored( ) data[ "note_num" ] = color. white( item[ 1 ] ) for pos in name: if data[ pos] == '' : data[ pos] = '-' tickets = [ ] cont = [ ] cont. append( data) for x in cont: tmp = [ ] for y in name: if y == "from_station_name" : s = color. green( station_names[ data[ 'from_station_name' ] ] ) + '\n' + color. red( station_names[ data[ "to_station_name" ] ] ) tmp. append( s) elif y == "start_time" : s = color. green( data[ 'start_time' ] ) + '\n' + color. red( data[ "arrive_time" ] ) tmp. append( s) elif y == "station_train_code" : s = color. blue( data[ 'station_train_code' ] ) tmp. append( s) else : tmp. append( data[ y] ) tickets. append( tmp) for ticket in tickets: table. add_row( ticket) print ( table) def get_secret_str ( self, from_station, to_station, train_date) : secret_str = { } result = self. get_tickets( from_station, to_station, train_date) result = result[ 'data' ] [ 'result' ] for item in result: msg = item. split( "|" ) secret_str[ msg[ 3 ] ] = parse. unquote( msg[ 0 ] ) return secret_strdef get_seats ( self, station_train_code, from_station, to_station, train_date) : seats = { } result = self. get_tickets( from_station, to_station, train_date) result = result[ 'data' ] [ 'result' ] for item in result: item = item. split( "|" ) if item[ 3 ] == station_train_code : seats[ 'swz_num' ] = item[ 32 ] or item[ 25 ] seats[ 'zy_num' ] = item[ 31 ] seats[ 'ze_num' ] = item[ 30 ] seats[ 'gr_num' ] = item[ 21 ] seats[ 'rw_num' ] = item[ 23 ] seats[ 'dw_num' ] = item[ 27 ] seats[ 'yw_num' ] = item[ 28 ] seats[ 'rz_num' ] = item[ 24 ] seats[ 'yz_num' ] = item[ 29 ] seats[ 'wz_num' ] = item[ 26 ] return seatsdef select_order_details ( self) : print ( "座位码对照表:" ) print ( "-----------------------" ) print ( "| 序号 | 座位类型 |" ) print ( "| M | 一等座 |" ) print ( "| 0 | 二等座 |" ) print ( "| 1 | 硬座 |" ) print ( "| N | 无座 |" ) print ( "| 2 | 软座 |" ) print ( "| 3 | 硬卧 |" ) print ( "| 4 | 软卧 |" ) print ( "| F | 动卧 |" ) print ( "| 6 | 高级软卧 |" ) print ( "| 9 | 商务座 |" ) print ( "-----------------------" ) seatType = input ( "请选择车座类型,enter键默认硬座(例如:1):" ) if seatType == '' : self. seatType = "1" elif seatType in self. seat_types_code: self. seatType = seatTypeelse : raise Exception( "没有对应的车座类型!" ) print ( "车票类型对照表:" ) print ( "-----------------------" ) print ( "| 序号 | 座位类型 |" ) print ( "| 1 | 成人票 |" ) print ( "| 2 | 儿童票 |" ) print ( "| 3 | 学生票 |" ) print ( "| 4 | 残军票 |" ) print ( "-----------------------" ) ticketType = input ( "请选择车票类型,enter键默认成人票(例如:1):" ) self. ticketType = ticketType if seatType != '' else "1" passengers_name = input ( "请输入乘车人姓名,如有多人,请以英文','隔开(例如:晏沈威,晏文艳):" ) self. passengers_name = passengers_name if passengers_name!= '' else '晏沈威' email = input ( "请输入发送提醒的邮箱(例如:wsyjlly@foxmai.com):" ) self. receive_email = email if email!= '' else "wsyjlly@foxmail.com" phone_number = input ( "请输入发送提醒的手机号(例如:13781206061):" ) self. phone_number = phone_number if phone_number!= '' else "13781206061" def query_ticket ( self, seats, seat_msg) : if ( ( seats[ seat_msg] == "" ) | ( seats[ seat_msg] == "无" ) ) : print ( "无" , self. seat_dict[ seat_msg] , "座位!" ) return False else : print ( "查询到" , seats[ seat_msg] , self. seat_dict[ seat_msg] , "座位!" ) return True def sys_seek_tickets ( self) : while True : from_station_name = "郑州" from_station_name = input ( "出发站点(例:郑州):" ) to_station_name = "开封" to_station_name = input ( "到达站点(例:开封):" ) train_date = "2019-02-28" train_date = ( input ( "乘车日期(例:2019-02-25):" ) ) print ( "正在为您查询余票信息,请稍等..." ) from_station = self. get_city_code( from_station_name) to_station = self. get_city_code( to_station_name) self. get_ticket_format( from_station_name, from_station, to_station_name, to_station, train_date) if input ( "输入'1'可继续查询,输入enter键选择车次!" ) != "1" : break station_train_code = "K464" station_train_code = input ( "乘车车次(例:K464):" ) self. select_order_details( ) while True : seats = self. get_seats( station_train_code, from_station, to_station, train_date) print ( '第{}次查票!' . format ( self. query_seats_count) , seats) if ( self. seatType== "1" ) : if self. query_ticket( seats, "yz_num" ) == True : break elif ( self. seatType== "N" ) : if self. query_ticket( seats, "wz_num" ) == True : break elif ( self. seatType== "2" ) : if self. query_ticket( seats, "rz_num" ) == True : break elif ( self. seatType== "3" ) : if self. query_ticket( seats, "yw_num" ) == True : break elif ( self. seatType== "4" ) : if self. query_ticket( seats, "rw_num" ) == True : break elif ( self. seatType== "6" ) : if self. query_ticket( seats, "gr_num" ) == True : break elif ( self. seatType== "0" ) : if self. query_ticket( seats, "ze_num" ) == True : break elif ( self. seatType== "M" ) : if self. query_ticket( seats, "zy_num" ) == True : break elif ( self. seatType== "F" ) : if self. query_ticket( seats, "dw_num" ) == True : break elif ( self. seatType== "9" ) : if self. query_ticket( seats, "swz_num" ) == True : break else : raise Exception( "没有相应车次!" ) break self. query_seats_count+= 1 time. sleep( 2 ) secret_str = self. get_secret_str( from_station, to_station, train_date) [ station_train_code] result = { } result[ "from_station" ] = from_stationresult[ "to_station" ] = to_stationresult[ "train_date" ] = train_dateresult[ "secret_str" ] = secret_strreturn result"""订单模块:1、注入起始点、日期,车次码信息,提交请求,返回状态信息2、获取该车次的详细信息,选择车票类型3、获取所有已添加乘客4、选择乘车乘客5、检查订单信息6、确认订单信息,占座成功,下单完成7、发送邮件,短信,提醒支付""" def get_train_number ( self, tickets) : secret_str = parse. unquote( tickets[ "secret_str" ] ) from_station = tickets[ "from_station" ] to_station = tickets[ "to_station" ] train_date = tickets[ "train_date" ] req = request. Request( 'https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest' ) req. headers = self. headersdata = { "secretStr" : secret_str, "train_date" : train_date, "back_train_date" : "" , "tour_flag" : "dc" , "purpose_codes" : "ADULT" , "query_from_station_name" : from_station, "query_to_station_name" : to_station, "undefined" : "" , } data = parse. urlencode( data) . encode( ) result = self. opener. open ( req, data= data) . read( ) . decode( ) return loads( result) def get_train_number_msg ( self) : req = request. Request( 'https://kyfw.12306.cn/otn/confirmPassenger/initDc' ) req. headers = self. headersdata = { "_json_att" : "" } data = parse. urlencode( data) . encode( ) result = self. opener. open ( req, data= data) . read( ) . decode( ) try : ticketInfoForPassengerForm = re. findall( "var ticketInfoForPassengerForm=(.*?);" , result) [ 0 ] . replace( "'" , '"' ) globalRepeatSubmitToken = re. findall( "globalRepeatSubmitToken = '(.*?)'" , result) [ 0 ] key_check_isChange = re. findall( "'key_check_isChange':'(.*?)'" , result) [ 0 ] except : raise Exception( "没有获取到车次信息!" ) ticketInfoForPassengerForm = loads( ticketInfoForPassengerForm) leftDetails = ticketInfoForPassengerForm[ "leftDetails" ] leftTicketStr = ticketInfoForPassengerForm[ "leftTicketStr" ] purpose_codes = ticketInfoForPassengerForm[ "queryLeftTicketRequestDTO" ] [ "purpose_codes" ] train_location = ticketInfoForPassengerForm[ "train_location" ] print ( "该车次剩余车票详情如下:" ) for item in leftDetails: print ( "\t" , item) msg_order_finally_submit = { } msg_order_finally_submit[ "purpose_codes" ] = purpose_codesmsg_order_finally_submit[ "key_check_isChange" ] = key_check_isChangemsg_order_finally_submit[ "leftTicketStr" ] = leftTicketStrmsg_order_finally_submit[ "train_location" ] = train_locationmsg_order_finally_submit[ "token" ] = globalRepeatSubmitTokenreturn msg_order_finally_submitdef get_passengers ( self, token) : req = request. Request( 'https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs' ) req. headers = self. headersdata = { "_json_att" : "" , "REPEAT_SUBMIT_TOKEN" : token} data = parse. urlencode( data) . encode( ) result = self. opener. open ( req, data= data) . read( ) . decode( ) result = loads( result) normal_passengers = result[ "data" ] [ "normal_passengers" ] result = { } for passenger in normal_passengers: result[ passenger[ "passenger_name" ] ] = passengerreturn resultdef select_passenger ( self, passengers) : ps = self. passengers_nameoldPassengerStr = '' passengerTicketStr = '' seatType = 1 if self. seatType == "N" else self. seatTypetry : ps = ps. split( "," ) for p in ps: oldPassengerStr += passengers[ p] [ "passenger_name" ] + "," + \passengers[ p] [ "passenger_id_type_code" ] + "," + \passengers[ p] [ "passenger_id_no" ] + "," + \passengers[ p] [ "passenger_type" ] + "_" ticketStr = "{},{},{},{},{},{},{},N" . format ( seatType, passengers[ p] [ "passenger_flag" ] , self. ticketType, passengers[ p] [ "passenger_name" ] , passengers[ p] [ "passenger_id_type_code" ] , passengers[ p] [ "passenger_id_no" ] , passengers[ p] [ "mobile_no" ] ) passengerTicketStr += ticketStr + '_' if p != ps[ len ( ps) - 1 ] else ticketStrexcept : print ( "输入有误!" ) result = { } result[ "oldPassengerStr" ] = oldPassengerStrresult[ "passengerTicketStr" ] = passengerTicketStrreturn resultdef order_submit ( self, msg_passenger, token) : req = request. Request( 'https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo' ) req. headers = self. headersdata = { "cancel_flag" : "2" , "bed_level_order_num" : "000000000000000000000000000000" , "passengerTicketStr" : msg_passenger[ "passengerTicketStr" ] , "oldPassengerStr" : msg_passenger[ "oldPassengerStr" ] , "tour_flag" : "dc" , "randCode" : "" , "whatsSelect" : "1" , "_json_att" : "" , "REPEAT_SUBMIT_TOKEN" : token} data = parse. urlencode( data) . encode( ) result = self. opener. open ( req, data= data) . read( ) . decode( ) return loads( result) def order_ensure ( self, msg_passenger, train_number_msg) : purpose_codes = train_number_msg[ "purpose_codes" ] key_check_isChange = train_number_msg[ "key_check_isChange" ] leftTicketStr = train_number_msg[ "leftTicketStr" ] train_location = train_number_msg[ "train_location" ] token = train_number_msg[ "token" ] req = request. Request( 'https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue' ) req. headers = self. headersdata = { "passengerTicketStr" : msg_passenger[ "passengerTicketStr" ] , "oldPassengerStr" : msg_passenger[ "oldPassengerStr" ] , "randCode" : "" , "purpose_codes" : purpose_codes, "key_check_isChange" : key_check_isChange, "leftTicketStr" : leftTicketStr, "train_location" : train_location, "choose_seats" : "" , "seatDetailType" : "000" , "whatsSelect" : "1" , "roomType" : "00" , "dwAll" : "N" , "_json_att" : "" , "REPEAT_SUBMIT_TOKEN" : token} data = parse. urlencode( data) . encode( ) result = self. opener. open ( req, data= data) . read( ) . decode( ) return loads( result) def send_email ( self) : mail_host = "smtp.qq.com" mail_user = "*******@foxmail.com" mail_pass = "****************" sender = "wsyjlly@foxmail.com" receiver = self. receive_emailmessage = MIMEText( "席位已锁定,快去支付!" ) message[ "From" ] = sendermessage[ "To" ] = receivermessage[ "Subject" ] = "Python 12306 抢票!" try : server = smtplib. SMTP( ) server. connect( mail_host) server. login( mail_user, mail_pass) server. sendmail( sender, receiver, message. as_string( ) ) server. close( ) print ( "邮件发送成功,已提醒用户" , receiver, "付款!" ) except Exception as e: print ( "邮件发送失败!" , e) def send_short_message ( self) : name = self. usernamephone_number = self. phone_numberseat_type = self. seatTypes[ self. seatType] ticketType = self. ticketTypes[ self. ticketType] appid = 1400 ** ** ** appkey = "********************************" phone_numbers = [ phone_number] template_id = ** ** ** sms_sign = "简单点网" ssender = SmsSingleSender( appid, appkey) params = [ name, ticketType, seat_type] try : result = ssender. send_with_param( 86 , phone_numbers[ 0 ] , template_id, params, sign= sms_sign, extend= "" , ext= "" ) except HTTPError as e: print ( e) except Exception as e: print ( e) if result[ "errmsg" ] == "OK" : print ( "短信发送成功,已提醒用户" , name, "付款!" ) def sys_order ( self, tickets) : result = self. get_train_number( tickets) if result[ "status" ] == True : print ( "查询车次信息成功!" ) train_number_msg = self. get_train_number_msg( ) passengers = self. get_passengers( train_number_msg[ "token" ] ) msg_passenger = self. select_passenger( passengers) result = self. order_submit( msg_passenger, train_number_msg[ "token" ] ) if result[ "status" ] == True : print ( "检查订单信息正确,即将确认订单!" ) print ( time. strftime( '%Y-%m-%d %H:%M:%S' , time. localtime( time. time( ) ) ) ) result = self. order_ensure( msg_passenger, train_number_msg) if result[ "status" ] == True : print ( time. strftime( '%Y-%m-%d %H:%M:%S' , time. localtime( time. time( ) ) ) , ":下单成功,已占座,请尽快付款!" ) self. send_email( ) self. send_short_message( ) input ( "按任意键继续!" ) def run ( self) : self. sys_verify( ) self. sys_login( ) tickets = self. sys_seek_tickets( ) self. sys_order( tickets) if __name__ == '__main__' : while True : train_ticket_purchase( ) . run( )