买票
提交订单。将需要购买的火车票提交上去。之间会使用在查询时的所需要的参数。
- 获取 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