12306 提交订单

买票

提交订单。将需要购买的火车票提交上去。之间会使用在查询时的所需要的参数。
  • 获取 cookie 防止提交订单时提交失败。这也是 12306 的反爬。
url = 'https://kyfw.12306.cn/otn/login/checkUser'
data = {
    '_json_att': ''
    }
response = self.session.post(url=url,data=data,headers=headers,verify=False)
  • 提交 cookie ,但这次提交时需要使用在查询列车时所需要的 secretStr
url = 'https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest'
data = {
'secretStr':urllib.parse.unquote(self.secretStr[getData2['train_station']]),#注意这里需要转码不然第二次请求会失败    'train_date':getData1['train_date'],
'back_train_date': getData1['back_traib_date'],
'tour_flag': 'dc',#特殊动车为  'wc' 
'purpose_codes': 'ADULT',
'query_from_station_name': getData1['from_station'],    'query_to_station_name': getData1['to_station'],
'undefined': ''
}
response=self.session.post(url=url,data=data,headers=headers,verify=False)
  • 获取在提交订单时所需要的 repeat_Token,key_check_isChange。使用正则查找。
#获取后面需要 globalRepeatSubmitToken 请求的参数
url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
data = {
    '_json_att':''
}
response=self.session.post(url=url,data=data,headers=headers,verify=False)
r = r"globalRepeatSubmitToken = '(.*?)';"
#预编译正则
compile = re.compile(r)
self.repeat_Token = re.findall(compile,str(response.text))[0]
r = r"'key_check_isChange':'(.*?)'"
compile = re.compile(r)
self.key_check_isChange = re.findall(compile,str(response.text))[0]
  • 查看常用联系人,购买车票也就只能用常用联系人。如果未在常用联系人中需要审核所以将会购买车票失败。
#获取可以购买的火车票常用联系人
url = 'https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs'
data = { 
    '_json_att':'',
    'REPEAT_SUBMIT_TOKEN':self.repeat_Token#刚才获取的 repeat_Token
}
response = self.session.post(url=url, data=data, headers=headers, verify=False)
# Json 格式解析返回的数据
content = loads(response.content)
for passenger in content['data']['normal_passengers']:
    self.passenger[passenger['passenger_name']] = passenger['passenger_id_no']
    #常用联系人的名字
    print(passenger['passenger_name'])
    #常用联系人的身份证
    print(passenger['passenger_id_no'])
    #常用联系人的电话
    print(passenger['mobile_no'])
    #常用联系人的 email
    print(passenger['email'])
  • 获取需要购买车票的信息并转变格式。
#获取购买车票的信息 也可以购买多张车票。如果嫌麻烦可以直接在 getData3 中写死
name = input('请输入需要购买车票的名字')
seatType = input('请输入购买火车票的座次')
pasType = input('请输入购买车票的类型')
getData3['passengerInfo'][0]['passengerName'] = name
getData3['passengerInfo'][0]['IDCard'] = self.passenger[name]
getData3['passengerInfo'][0]['seatType'] = seatType
getData3['passengerInfo'][0]['pasType'] = pasType
#将需要购买的车票信息转化格式
ticketStr = changeTicket(getData3)
  • 提交订单第一步。
#提交订单第一步
url = 'https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo'
data = {
    'cancel_flag': '2',
    'bed_level_order_num': '000000000000000000000000000000',
    'passengerTicketStr': ticketStr['passengerTicketStr'],#转化格式后的数据 
    oldPassengerStr': ticketStr['oldPassengerStr'],#转化格式后的数据
    'tour_flag': 'dc',
    'randCode':'', 
    'whatsSelect': '1',
    '_json_att':'', 
    'REPEAT_SUBMIT_TOKEN': self.repeat_Token# 第一步获取的 repeat_Token
}
response = self.session.post(url=url, data=data, headers=headers,verify=False)
  • 提交订单第二步
# 提交订单第二步
url = 'https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount'
data = {
    'train_date': changeTrainDate(getData1['train_date']),#转变出发时间格式
    'train_no': self.train_no[getData2['train_station']],#列车的 no
    'stationTrainCode': getData2['train_station'],#需要购买的车票车次
    'seatType': getSeatType(getData3['passengerInfo'][0]['seatType']),# 座次代号 
    'fromStationTelecode': code[getData1['from_station']],#发出地代号
    'toStationTelecode': code[getData1['to_station']],#到达地代号
    'leftTicket': self.leftTicket[getData2['train_station']],
    'purpose_codes': '00',
    'train_location': self.train_location[getData2['train_station']],
    '_json_att': '',
    'REPEAT_SUBMIT_TOKEN': self.repeat_Token# 第一步获取的 repeat_Token
}
response = self.session.post(url=url, data=data,headers=headers,verify=False)
  • 提交订单第三步
url = 'https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue'
data = { 
    'passengerTicketStr': ticketStr['passengerTicketStr'], 
    'oldPassengerStr': ticketStr['oldPassengerStr'],
    'randCode': '',
    'purpose_codes': '00',
    'key_check_isChange': self.key_check_isChange,## 第一步获取的 key_check_isChange    'leftTicketStr': self.leftTicket[getData2['train_station']],
    'train_location': self.train_location[getData2['train_station']],
    'choose_seats': '', 
    'seatDetailType': '000',
    'whatsSelect': '1',
    'roomType': '00',
    'dwAll': 'N',
    '_json_att': '',
    'REPEAT_SUBMIT_TOKEN': self.repeat_Token# 第一步获取的 repeat_Token
    }
response = self.session.post(url=url,data=data,headers=headers,verify=False)
print('confirmSingleForQueue',response.text)

提交上去后就完成购票了,这里需要去 12306 官网去支付,注意只有 30 分钟支付时间。超时后只能重新购买车票了

QQ截图20190311102020.png

github(https://github.com/Tedgar156/12306/tree/master)
如果觉得有用请点一下 star

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、产品概述 1.体验环境 体验机型:华为荣耀6 plus 安卓版本:4.4.2 体验版本:2.92 体验时间:2...
    Juanial阅读 14,054评论 0 14
  • 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Se...
    chinariver阅读 10,956评论 1 49
  • 什么是好人,什么是坏人?我们时常分不清好人和坏人,就像我们分不清天空和大海。 老人摔倒了,善良的我们把她扶了起来,...
    艾升活矮子油阅读 2,767评论 0 0
  • 《想你,是我给这片天空的承诺》 宿命的青花瓷勾勒的爱怜, 我在天青色中启程, 把所有的疲惫,哀愁与迷茫都留给这片天...
    野心要优雅哦阅读 1,040评论 0 0
  • 原创/想无昵称 不喜热闹不是因为孤僻 而只是害怕别离 不喜与人同榻不是因为自私 而只是需要空间 不喜助人不是因为懒...
    想无昵称阅读 1,423评论 0 3