Python抢票系统:自动购票脚本实战指南
抢票系统是一个复杂的程序,需要涉及到网站登录、查询、购票等多个过程。以下是一个简单的抢票程序,仅供参考。
import requests
import time
# 12306网站登录信息
username = 'your_username'
password = 'your_password'
# 出发日期、出发城市、到达城市、乘车人信息
date = '2022-01-01'
from_station = '北京'
to_station = '上海'
passengers = [{'name': '张三', 'id': '110101199001010001', 'phone': '13800000000'}]
# 登录12306网站
def login():
url = 'https://kyfw.12306.cn/otn/login/init'
session = requests.Session()
session.get(url)
login_url = 'https://kyfw.12306.cn/passport/web/login'
data = {
'username': username,
'password': password,
'appid': 'otn'
}
response = session.post(login_url, data=data)
if response.json()['result_code'] == 0:
print('登录成功')
return session
else:
print('登录失败')
return None
# 查询车票信息
def query(session):
url = f'https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={date}&leftTicketDTO.from_station={from_station}&leftTicketDTO.to_station={to_station}&purpose_codes=ADULT'
response = session.get(url)
data = response.json()['data']
tickets = []
for item in data:
ticket = {}
ticket['train_no'] = item['queryLeftNewDTO']['train_no']
ticket['station_train_code'] = item['queryLeftNewDTO']['station_train_code']
ticket['from_station_name'] = item['queryLeftNewDTO']['from_station_name']
ticket['to_station_name'] = item['queryLeftNewDTO']['to_station_name']
ticket['start_time'] = item['queryLeftNewDTO']['start_time']
ticket['arrive_time'] = item['queryLeftNewDTO']['arrive_time']
ticket['lishi'] = item['queryLeftNewDTO']['lishi']
ticket['swz_num'] = item['queryLeftNewDTO']['swz_num']
ticket['zy_num'] = item['queryLeftNewDTO']['zy_num']
ticket['ze_num'] = item['queryLeftNewDTO']['ze_num']
ticket['gr_num'] = item['queryLeftNewDTO']['gr_num']
ticket['rw_num'] = item['queryLeftNewDTO']['rw_num']
ticket['yw_num'] = item['queryLeftNewDTO']['yw_num']
ticket['rz_num'] = item['queryLeftNewDTO']['rz_num']
ticket['yz_num'] = item['queryLeftNewDTO']['yz_num']
ticket['wz_num'] = item['queryLeftNewDTO']['wz_num']
tickets.append(ticket)
return tickets
# 购买车票
def buy(session, ticket, passenger):
url = 'https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest'
data = {
'secretStr': ticket['secretStr'],
'train_date': date,
'back_train_date': date,
'tour_flag': 'dc',
'purpose_codes': 'ADULT',
'query_from_station_name': from_station,
'query_to_station_name': to_station,
'undefined': ''
}
response = session.post(url, data=data)
if response.json()['status']:
print('提交订单成功')
else:
print('提交订单失败')
return False
time.sleep(1)
url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
response = session.get(url)
token = response.text.split(''globalRepeatSubmitToken'')[1].split('= '')[1].split(''')[0]
key_check_isChange = response.text.split(''key_check_isChange'')[1].split('= '')[1].split(''')[0]
url = 'https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs'
data = {'_json_att': '', 'REPEAT_SUBMIT_TOKEN': token}
response = session.post(url, data=data)
passengers = response.json()['data']['normal_passengers']
passenger = next(filter(lambda x: x['passenger_name'] == passenger['name'], passengers), None)
if not passenger:
print('乘车人不存在')
return False
url = 'https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo'
data = {
'cancel_flag': 2,
'bed_level_order_num': '000000000000000000000000000000',
'passengerTicketStr': f'O,0,1,{passenger['passenger_name']},1,{passenger['passenger_id_no']},{passenger['mobile_no']},N',
'oldPassengerStr': f'{passenger['passenger_name']},1,{passenger['passenger_id_no']}',
'tour_flag': 'dc',
'randCode': '',
'whatsSelect': 1,
'_json_att': '',
'REPEAT_SUBMIT_TOKEN': token
}
response = session.post(url, data=data)
if response.json()['status']:
print('校验订单信息成功')
else:
print('校验订单信息失败')
return False
url = 'https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount'
data = {
'train_date': time.strftime('%a %b %d %Y %H:%M:%S', time.strptime(date, '%Y-%m-%d')),
'train_no': ticket['train_no'],
'stationTrainCode': ticket['station_train_code'],
'seatType': 'O',
'fromStationTelecode': '',
'toStationTelecode': '',
'leftTicket': ticket['secretStr'],
'purpose_codes': '00',
'train_location': '',
'_json_att': '',
'REPEAT_SUBMIT_TOKEN': token
}
response = session.post(url, data=data)
if response.json()['status']:
print('查询余票信息成功')
else:
print('查询余票信息失败')
return False
url = 'https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue'
data = {
'passengerTicketStr': f'O,0,1,{passenger['passenger_name']},1,{passenger['passenger_id_no']},{passenger['mobile_no']},N',
'oldPassengerStr': f'{passenger['passenger_name']},1,{passenger['passenger_id_no']}',
'randCode': '',
'purpose_codes': '00',
'key_check_isChange': key_check_isChange,
'leftTicketStr': ticket['secretStr'],
'train_location': '',
'choose_seats': '',
'seatDetailType': '',
'whatsSelect': '1',
'roomType': '00',
'dwAll': 'N',
'_json_att': '',
'REPEAT_SUBMIT_TOKEN': token
}
response = session.post(url, data=data)
if response.json()['status']:
print('提交订单成功')
else:
print('提交订单失败')
return False
url = 'https://kyfw.12306.cn/otn/confirmPassenger/resultOrderForDcQueue'
data = {
'orderSequence_no': '',
'_json_att': '',
'REPEAT_SUBMIT_TOKEN': token
}
while True:
response = session.post(url, data=data)
if response.json()['status']:
if response.json()['data']['submitStatus']:
print('购票成功')
return True
elif response.json()['data']['errMsg']:
print(response.json()['data']['errMsg'])
return False
time.sleep(3)
# 主函数
if __name__ == '__main__':
session = login()
if session:
print('查询车票信息...')
tickets = query(session)
if len(tickets) == 0:
print('无车票信息')
else:
for ticket in tickets:
print(f'{ticket['station_train_code']} {ticket['from_station_name']} -> {ticket['to_station_name']} {ticket['start_time']} - {ticket['arrive_time']}')
if ticket['swz_num'] != '--':
print('商务座有票,购票中...')
for passenger in passengers:
if buy(session, ticket, passenger):
break
else:
print(f'{passenger['name']} 购票失败')
break
elif ticket['zy_num'] != '--':
print('一等座有票,购票中...')
for passenger in passengers:
if buy(session, ticket, passenger):
break
else:
print(f'{passenger['name']} 购票失败')
break
elif ticket['ze_num'] != '--':
print('二等座有票,购票中...')
for passenger in passengers:
if buy(session, ticket, passenger):
break
else:
print(f'{passenger['name']} 购票失败')
break
else:
print('无票信息')
else:
print('登录失败')
该程序的实现需要注意以下几点:
- 登录12306网站需要使用Session,以保持登录状态。
- 查询车票信息需要使用正确的URL和参数,返回的数据需要进行解析。
- 购买车票需要分多个步骤进行,每个步骤都需要正确的URL和参数,同时需要注意提交订单和查询订单状态的时间间隔。
- 乘车人信息需要提前在12306网站上添加。
虽然该程序可以实现抢票功能,但仍存在一定的风险和局限性。建议在使用前仔细阅读相关法律法规和网站规定,谨慎使用。
原文地址: https://www.cveoy.top/t/topic/lAiE 著作权归作者所有。请勿转载和采集!