12306抢票脚本 python
时间: 2023-09-22 08:14:04 浏览: 72
抢票是一个比较复杂的过程,需要了解一些网络编程和爬虫技术。以下是一个基本的抢票脚本框架,需要根据具体情况进行修改和调整:
```
# -*- coding:utf-8 -*-
import time
import requests
import json
# 设置会话
s = requests.session()
# 设置请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
# 设置起点和终点
start_station = ''
end_station = ''
# 设置乘车日期和车次
train_date = ''
train_number = ''
# 设置乘客姓名和身份证号
passenger_name = ''
passenger_id = ''
# 获取余票信息
def get_ticket_info(train_date, start_station, end_station, train_number):
url = 'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT'.format(train_date, start_station, end_station)
response = s.get(url, headers=headers, verify=False)
result = json.loads(response.text)
data = result['data']
for item in data:
if train_number in item['queryLeftNewDTO']['station_train_code']:
left_ticket = item['queryLeftNewDTO']['ze_num']
return left_ticket
# 提交订单
def submit_order_request():
url = 'https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest'
data = {
'secretStr': '',
'train_date': train_date,
'back_train_date': '',
'tour_flag': 'dc',
'purpose_codes': 'ADULT',
'query_from_station_name': '',
'query_to_station_name': '',
'undefined': ''
}
response = s.post(url, headers=headers, data=data, verify=False)
result = json.loads(response.text)
if result['status'] == True:
return True
else:
return False
# 获取乘客信息和座位信息
def get_passenger_info():
url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
response = s.get(url, headers=headers, verify=False)
result = json.loads(response.text)
data = result['data']
ticket_info_for_passenger_form = data['ticketInfoForPassengerForm']
global_submit_token = data['globalRepeatSubmitToken']
passenger_info = {
'passengerTicketStr': 'O,0,1,{},1,{},N'.format(passenger_name, passenger_id),
'oldPassengerStr': '{},1,{},3_'.format(passenger_name, passenger_id)
}
return ticket_info_for_passenger_form, global_submit_token, passenger_info
# 检查订单信息
def check_order_info(ticket_info_for_passenger_form, global_submit_token, passenger_info):
url = 'https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo'
data = {
'cancel_flag': '2',
'bed_level_order_num': '000000000000000000000000000000',
'passengerTicketStr': passenger_info['passengerTicketStr'],
'oldPassengerStr': passenger_info['oldPassengerStr'],
'tour_flag': 'dc',
'randCode': '',
'whatsSelect': '1',
'_json_att': '',
'REPEAT_SUBMIT_TOKEN': global_submit_token
}
response = s.post(url, headers=headers, data=data, verify=False)
result = json.loads(response.text)
if result['status'] == True:
return True
else:
return False
# 获取排队信息
def get_queue_count(train_date, train_number, start_station, end_station, ticket_info_for_passenger_form, global_submit_token):
url = 'https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount'
data = {
'train_date': train_date,
'train_no': ticket_info_for_passenger_form['queryLeftTicketRequestDTO']['train_no'],
'stationTrainCode': train_number,
'seatType': 'O',
'fromStationTelecode': start_station,
'toStationTelecode': end_station,
'leftTicket': ticket_info_for_passenger_form['leftTicketStr'],
'purpose_codes': '00',
'train_location': ticket_info_for_passenger_form['train_location'],
'_json_att': '',
'REPEAT_SUBMIT_TOKEN': global_submit_token
}
response = s.post(url, headers=headers, data=data, verify=False)
result = json.loads(response.text)
if result['status'] == True:
if int(result['data']['ticket']) > 0:
return True, result['data']['ticket']
else:
return False, 0
else:
return False, 0
# 提交订单
def confirm_single_for_queue(ticket_info_for_passenger_form, global_submit_token, passenger_info, ticket_count):
url = 'https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue'
data = {
'passengerTicketStr': passenger_info['passengerTicketStr'],
'oldPassengerStr': passenger_info['oldPassengerStr'],
'randCode': '',
'purpose_codes': '00',
'key_check_isChange': ticket_info_for_passenger_form['key_check_isChange'],
'leftTicketStr': ticket_info_for_passenger_form['leftTicketStr'],
'train_location': ticket_info_for_passenger_form['train_location'],
'choose_seats': '',
'seatDetailType': '000',
'whatsSelect': '1',
'roomType': '00',
'dwAll': 'N',
'_json_att': '',
'REPEAT_SUBMIT_TOKEN': global_submit_token
}
response = s.post(url, headers=headers, data=data, verify=False)
result = json.loads(response.text)
if result['status'] == True:
orderId = result['data']['orderId']
return orderId
else:
return False
# 轮询等待订单结果
def query_order_wait_time(orderId):
url = 'https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime?random={}&tourFlag=dc&_json_att=&REPEAT_SUBMIT_TOKEN={}&orderId={}'.format(int(time.time() * 1000), global_submit_token, orderId)
response = s.get(url, headers=headers, verify=False)
result = json.loads(response.text)
if result['status'] == True:
if result['data']['waitTime'] == -1:
if result['data']['orderStatus'] == 2:
return True
else:
return False
else:
time.sleep(5)
return query_order_wait_time(orderId)
else:
return False
# 主函数
def main():
while True:
left_ticket = get_ticket_info(train_date, start_station, end_station, train_number)
if left_ticket != '无' and int(left_ticket) > 0:
print('当前余票数量为:{}'.format(left_ticket))
if submit_order_request():
print('提交订单成功!')
ticket_info_for_passenger_form, global_submit_token, passenger_info = get_passenger_info()
if check_order_info(ticket_info_for_passenger_form, global_submit_token, passenger_info):
print('检查订单信息成功!')
flag, ticket_count = get_queue_count(train_date, train_number, start_station, end_station, ticket_info_for_passenger_form, global_submit_token)
if flag:
print('排队成功,当前排队人数为{}'.format(ticket_count))
orderId = confirm_single_for_queue(ticket_info_for_passenger_form, global_submit_token, passenger_info, ticket_count)
if orderId:
print('下单成功,订单号为:{}'.format(orderId))
if query_order_wait_time(orderId):
print('支付成功!')
break
else:
print('支付失败!')
else:
print('排队失败!')
else:
print('检查订单信息失败!')
else:
print('提交订单失败!')
else:
print('当前余票不足,正在重试...')
time.sleep(1)
if __name__ == '__main__':
main()
```
需要注意的是,12306的API接口随时可能会发生变化,所以具体的实现方式可能需要根据最新的接口文档进行调整。
阅读全文