抢火车票的实现思路如下:

  1. 登录 12306 网站,获取用户登录后的 cookie 信息
  2. 输入出发日期和出发地点、目的地点等信息,获取需要抢购的车票的相关信息,如车次、座位类型、价格等
  3. 模拟用户查询车票,并获取车票的余票信息
  4. 如果有余票,模拟用户提交订单
  5. 如果提交订单成功,模拟用户支付订单

具体实现代码如下:

import requests
import time

# 登录 12306 网站,获取 cookie
def login():
    url = 'https://kyfw.12306.cn/otn/login/init'
    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'
    }
    session = requests.Session()
    session.headers.update(headers)
    session.get(url)
    login_url = 'https://kyfw.12306.cn/passport/web/login'
    data = {
        'username': 'your_username',
        'password': 'your_password',
        'appid': 'otn'
    }
    session.post(login_url, data=data)
    return session.cookies

# 获取车票信息
def get_ticket_info(date, from_station, to_station, seat_type):
    url = 'https://kyfw.12306.cn/otn/leftTicket/queryZ'
    params = {
        'leftTicketDTO.train_date': date,
        'leftTicketDTO.from_station': from_station,
        'leftTicketDTO.to_station': to_station,
        'purpose_codes': 'ADULT'
    }
    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'
    }
    session = requests.Session()
    session.headers.update(headers)
    session.cookies = login()
    resp = session.get(url, params=params)
    data = resp.json()['data']
    for d in data:
        d = d['queryLeftNewDTO']
        if d['seat_types'].find(seat_type) != -1:
            return d['train_no'], d['from_station_telecode'], d['to_station_telecode'], d['start_time'], d['arrive_time'], d['lishi'], d['swz_num'], d['tz_num'], d['zy_num'], d['ze_num'], d['wz_num'], d['yb_num'], d['rw_num'], d['yw_num'], d['rz_num'], d['yz_num']
    return None

# 提交订单
def submit_order(date, train_no, from_station, to_station, seat_type, passengers):
    url = 'https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest'
    data = {
        'secretStr': '',
        'train_date': date,
        'back_train_date': date,
        'tour_flag': 'dc',
        'purpose_codes': 'ADULT',
        'query_from_station_name': '',
        'query_to_station_name': '',
        'undefined': ''
    }
    params = {
        'leftTicketDTO.train_no': train_no,
        'leftTicketDTO.train_date': date,
        'leftTicketDTO.station_train_code': '',
        'train_location': '',
        'stationTrainDTO.from_station_telecode': from_station,
        'stationTrainDTO.to_station_telecode': to_station,
        'stationTrainDTO.start_time': '',
        'stationTrainDTO.end_time': '',
        'stationTrainDTO.over_time': '',
        'stationTrainDTO.train_no': train_no,
        'stationTrainDTO.from_station_name': '',
        'stationTrainDTO.to_station_name': '',
        'passengerTicketStr': '',
        'oldPassengerStr': '',
        'randCode': '',
        'purpose_codes': '00',
        'key_check_isChange': ''
    }
    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',
        'Referer': 'https://kyfw.12306.cn/otn/leftTicket/init'
    }
    session = requests.Session()
    session.headers.update(headers)
    session.cookies = login()
    resp = session.post(url, data=data, params=params)
    if resp.json()['status']:
        url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
        data = {
            '_json_att': ''
        }
        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',
            'Referer': 'https://kyfw.12306.cn/otn/leftTicket/init'
        }
        session = requests.Session()
        session.headers.update(headers)
        session.cookies = login()
        session.post(url, data=data)
        url = 'https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs'
        data = {
            '_json_att': '',
            'REPEAT_SUBMIT_TOKEN': resp.json()['data']['submitToken']
        }
        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',
            'Referer': 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
        }
        session = requests.Session()
        session.headers.update(headers)
        session.cookies = login()
        resp = session.post(url, data=data)
        passenger_info = resp.json()['data']['normal_passengers']
        passenger_str_list = []
        for passenger in passenger_info:
            if passenger['passenger_name'] in passengers:
                passenger_str_list.append('{},{},{},{},{},{},{},N'.format(passenger['passenger_name'], passenger['passenger_id_type_code'], passenger['passenger_id_no'], passenger['mobile_no'], '1', '0', passenger['passenger_name']))
        url = 'https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo'
        data = {
            'cancel_flag': '2',
            'bed_level_order_num': '000000000000000000000000000000',
            'passengerTicketStr': '_'.join(passenger_str_list),
            'oldPassengerStr': '_'.join(passenger_str_list),
            'tour_flag': 'dc',
            'randCode': '',
            'whatsSelect': '1',
            '_json_att': '',
            'REPEAT_SUBMIT_TOKEN': resp.json()['data']['submitToken']
        }
        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',
            'Referer': 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
        }
        session = requests.Session()
        session.headers.update(headers)
        session.cookies = login()
        resp = session.post(url, data=data)
        if resp.json()['status']:
            url = 'https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount'
            data = {
                'train_date': time.strftime('%a %b %d %Y', time.strptime(date, '%Y-%m-%d')) + ' 00:00:00 GMT+0800 (中国标准时间)',
                'train_no': train_no,
                'stationTrainDTO.from_station_telecode': from_station,
                'stationTrainDTO.to_station_telecode': to_station,
                'seatType': seat_type,
                'leftTicket': '',
                'purpose_codes': '00',
                'train_location': '',
                '_json_att': '',
                'REPEAT_SUBMIT_TOKEN': resp.json()['data']['submitToken']
            }
            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',
                'Referer': 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
            }
            session = requests.Session()
            session.headers.update(headers)
            session.cookies = login()
            resp = session.post(url, data=data)
            if resp.json()['status']:
                url = 'https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue'
                data = {
                    'passengerTicketStr': '_'.join(passenger_str_list),
                    'oldPassengerStr': '_'.join(passenger_str_list),
                    'randCode': '',
                    'purpose_codes': '00',
                    'key_check_isChange': '',
                    'leftTicketStr': '',
                    'train_location': '',
                    'choose_seats': '',
                    'seatDetailType': '000',
                    'whatsSelect': '1',
                    'roomType': '00',
                    'dwAll': 'N',
                    '_json_att': '',
                    'REPEAT_SUBMIT_TOKEN': resp.json()['data']['submitToken']
                }
                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',
                    'Referer': 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
                }
                session = requests.Session()
                session.headers.update(headers)
                session.cookies = login()
                resp = session.post(url, data=data)
                if resp.json()['status']:
                    url = 'https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime'
                    data = {
                        'random': str(int(time.time())),
                        'tourFlag': 'dc',
                        '_json_att': '',
                        'REPEAT_SUBMIT_TOKEN': resp.json()['data']['submitToken']
                    }
                    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',
                        'Referer': 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
                    }
                    session = requests.Session()
                    session.headers.update(headers)
                    session.cookies = login()
                    while True:
                        resp = session.post(url, data=data)
                        if resp.json()['data']['waitTime'] == -1:
                            print('订票成功!')
                            return
                        time.sleep(1)

# 抢票
def snatch_ticket(date, from_station, to_station, seat_type, passengers):
    ticket_info = None
    while not ticket_info:
        print('正在尝试获取车票信息...')
        ticket_info = get_ticket_info(date, from_station, to_station, seat_type)
        time.sleep(1)
    print('车票信息:', ticket_info)
    submit_order(date, ticket_info[0], ticket_info[1], ticket_info[2], seat_type, passengers)

if __name__ == '__main__':
    snatch_ticket('2022-01-01', 'BJP', 'SHH', 'O', ['张三', '李四'])  # 示例:抢购 2022 年 1 月 1 日从北京到上海的 O 字头座位,乘客姓名为张三和李四

需要注意的是,这段代码仅供学习和参考使用,不应用于实际抢购车票中,因为 12306 网站严禁使用爬虫程序进行抢票。

Python 爬虫抢火车票:实现原理与代码示例

原文地址: https://www.cveoy.top/t/topic/o0d3 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录