買票
提交訂單。將需要購買的火車票提交上去。之間會(huì)使用在查詢時(shí)的所需要的參數(shù)。
- 獲取 cookie 防止提交訂單時(shí)提交失敗。這也是 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 ,但這次提交時(shí)需要使用在查詢列車時(shí)所需要的 secretStr
url = 'https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest'
data = {
'secretStr':urllib.parse.unquote(self.secretStr[getData2['train_station']]),#注意這里需要轉(zhuǎn)碼不然第二次請求會(huì)失敗 'train_date':getData1['train_date'],
'back_train_date': getData1['back_traib_date'],
'tour_flag': 'dc',#特殊動(dòng)車為 '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)
- 獲取在提交訂單時(shí)所需要的 repeat_Token,key_check_isChange。使用正則查找。
#獲取后面需要 globalRepeatSubmitToken 請求的參數(shù)
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 = '(.*?)';"
#預(yù)編譯正則
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]
- 查看常用聯(lián)系人,購買車票也就只能用常用聯(lián)系人。如果未在常用聯(lián)系人中需要審核所以將會(huì)購買車票失敗。
#獲取可以購買的火車票常用聯(lián)系人
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 格式解析返回的數(shù)據(jù)
content = loads(response.content)
for passenger in content['data']['normal_passengers']:
self.passenger[passenger['passenger_name']] = passenger['passenger_id_no']
#常用聯(lián)系人的名字
print(passenger['passenger_name'])
#常用聯(lián)系人的身份證
print(passenger['passenger_id_no'])
#常用聯(lián)系人的電話
print(passenger['mobile_no'])
#常用聯(lián)系人的 email
print(passenger['email'])
- 獲取需要購買車票的信息并轉(zhuǎn)變格式。
#獲取購買車票的信息 也可以購買多張車票。如果嫌麻煩可以直接在 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
#將需要購買的車票信息轉(zhuǎn)化格式
ticketStr = changeTicket(getData3)
- 提交訂單第一步。
#提交訂單第一步
url = 'https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo'
data = {
'cancel_flag': '2',
'bed_level_order_num': '000000000000000000000000000000',
'passengerTicketStr': ticketStr['passengerTicketStr'],#轉(zhuǎn)化格式后的數(shù)據(jù)
oldPassengerStr': ticketStr['oldPassengerStr'],#轉(zhuǎn)化格式后的數(shù)據(jù)
'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']),#轉(zhuǎn)變出發(fā)時(shí)間格式
'train_no': self.train_no[getData2['train_station']],#列車的 no
'stationTrainCode': getData2['train_station'],#需要購買的車票車次
'seatType': getSeatType(getData3['passengerInfo'][0]['seatType']),# 座次代號(hào)
'fromStationTelecode': code[getData1['from_station']],#發(fā)出地代號(hào)
'toStationTelecode': code[getData1['to_station']],#到達(dá)地代號(hào)
'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 官網(wǎng)去支付,注意只有 30 分鐘支付時(shí)間。超時(shí)后只能重新購買車票了

QQ截圖20190311102020.png
github(https://github.com/Tedgar156/12306/tree/master)
如果覺得有用請點(diǎn)一下 star