python的查车票小工具python购买火车票
需求概述
这是一个基于Python的火车票查询与购买小工具,主要包括两个功能:通过查询火车票余票信息,告知用户当前车次的余票情况,并支持实时提醒;自动登录12306网站,查询指定的出发时间、路线和座位类型的车票,并完成购买。
第一功能:火车票余票查询
实现火车票余票查询功能,主要需要搭建自己的查询接口,并根据接口返回的信息进行处理和展示。以下是一个简单的查询余票的Python代码示例:
import requests from pyquery import PyQuery as pq def queryTicket(train_no, from_station, to_station, date): query_url = 'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT'.format(date, from_station, to_station) res = requests.get(query_url, verify=False) if res.status_code == requests.codes.ok: data = res.json() tickets = {} for item in data['data']['result']: ticket_info = item.split('|') train_code = ticket_info[3] if train_code == train_no: arrive_time = ticket_info[8] left_time = ticket_info[9] seatTypes = [ {'name': '商务座', 'type': 'A9'}, {'name': '一等座', 'type': 'M'}, {'name': '二等座', 'type': 'O'}, {'name': '软卧', 'type': 'A4'}, {'name': '硬卧', 'type': 'A3'}, {'name': '硬座', 'type': 'A1'}, {'name': '无座', 'type': 'WZ'} ] seat_infos = {} for seat in seatTypes: if ticket_info[seat['type']] != '无' and ticket_info[seat['type']] != '': seat_info = {'name': seat['name'], 'count': ticket_info[seat['type']]} seat_infos.update({seat['type']: seat_info}) return {'train_code': train_code, 'arrive_time': arrive_time, 'left_time': left_time, 'seat_infos': seat_infos} return None # 样例调用 queryTicket('D1', 'BJP', 'SHH', '2018-10-01')
通过以上代码实现了查询余票的逻辑,其中train_no是指定的车次,from_station和to_station是相应的出发站和到达站的电报码,date是出发日期。代码首先构造了查询url,然后进行了接口调用,将返回数据封装到字典中进行处理,最后返回火车票的余票信息。
第二功能:火车票自动购买
自动购买火车票需要模拟用户在12306网站的登录和购买流程。首先需要访问12306的登录页面,获取动态生成的登录token,并根据用户名和密码生成加密后的密码,最后提交请求进行登录。接下来是购票过程,通过查询余票接口获取可用余票的信息,然后进行当前出发站和到达站的选择、座位类型的选择、乘客信息的填写、验证码的处理等步骤,完成相应的购票动作。以下是一个简单的Python代码示例:
import time import requests from pyquery import PyQuery as pq from urllib.parse import urlencode class TrainTickets: def __init__(self): self.login_url = 'https://kyfw.12306.cn/passport/web/login' self.index_url = 'https://kyfw.12306.cn/otn/index/initMy12306' self.order_url = 'https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest' self.initdc_url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc' self.check_order_url = 'https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo' self.confirm_order_url = 'https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue' self.login_data = { 'username': username, 'password': password, 'appid': 'otn' } self.passenger_name = passenger_name self.from_station = from_station self.to_station = to_station self.seat_type = seat_type self.depart_date = depart_date self.ticket_info = None self.token = None self.session = requests.Session() def login(self): self.session.post(self.login_url, data=self.login_data, headers=headers) resp = self.session.get(self.index_url, headers=headers) doc = pq(resp.text) my_name = doc('#my12306menu > div > div.welcome-info > span').text() if my_name: print('登录成功') else: print('登录失败') def get_train_info(self): query_url = 'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT'.format(self.depart_date, self.from_station, self.to_station) res = self.session.get(query_url, verify=False) if res.status_code == 200: data = res.json() for item in data['data']['result']: ticket_info = item.split('|') train_code = ticket_info[3] if train_code == self.train_no: # 解析余票信息 ... def submit_order(self): data = { 'secretStr': self.ticket_info['secretStr'], 'train_date': self.ticket_info['date'], 'back_train_date': self.ticket_info['date'], 'tour_flag': 'dc', 'purpose_codes': 'ADULT', 'query_from_station_name': self.from_station, 'query_to_station_name': self.to_station, 'undefined':'' } submit_url = self.order_url + '?' + urlencode(data) res = self.session.post(submit_url) if res.status_code == requests.codes.ok: print('订票成功') else: print('订票失败') def init_dc(self): data = { '_json_att': '', 'REPEAT_SUBMIT_TOKEN': self.token } res = self.session.post(self.initdc_url, data=data, headers=headers, verify=False) if res.status_code == 200: print('确认乘客') def check_order_info(self): passenger_data = { 'REPEAT_SUBMIT_TOKEN': self.token, 'checkBox': 'Y', 'bed_level_order_num': '000000000000000000000000000000', 'passengerTicketStr': 'O,0,1,{},1,{},{},N'.format(self.passenger_name, self.ticket_info['seat_type']), 'oldPassengerStr': '{},1,1,{}'.format(self.passenger_name, self.cert_no) } data = { 'cancel_flag': '2', 'bed_level_order_num': '000000000000000000000000000000', 'tour_flag': 'dc', 'randCode': '', '_json_att': '', 'REPEAT_SUBMIT_TOKEN': self.token } res = self.session.post(self.check_order_url, data=data, headers=headers, verify=False) if res.status_code == 200: if res.json()['data']['submitStatus']: print('提交成功') def confirm_order(self): passenger_data = { 'REPEAT_SUBMIT_TOKEN': self.token, 'checkBox': 'Y', 'bed_level_order_num': '000000000000000000000000000000', 'passengerTicketStr': 'O,0,1,{},,1,{},{},N'.format(self.passenger_name, self.ticket_info['seat_type']), 'oldPassengerStr': '{},1,1,{}'.format(self.passenger_name, self.cert_no) } data = { 'passengerTickets': passenger_data['passengerTicketStr'], 'oldPassengers': passenger_data['oldPassengerStr'], 'randCode': '', 'purpose_codes': '00', 'key_check_isChange': '', 'leftTicketStr': self.ticket_info['secretStr'], 'train_location': self.ticket_info['train_location'], 'choose_seats': '', 'seatDetailType': '000', 'whatsSelect': '1', 'roomType': '00', 'dwAll': 'N', '_json_att': '', 'REPEAT_SUBMIT_TOKEN': self.token } res = self.session.post(self.confirm_order_url, data=data, headers=headers, verify=False) if res.status_code == 200: data = res.json() if data['data']['submitStatus']: print('购买成功') ticket = TrainTickets() ticket.login() ticket.get_train_info() ticket.submit_order() ticket.init_dc() ticket.check_order_info() ticket.confirm_order()
以上是一个模拟12306网站登录和购票流程的Python代码示例,代码中需要填写的部分主要是用户名、密码、乘客名、证件号、出发站电报码、到达站电报码、座位类型和出发日期。模拟登录过程中需要通过正则表达式或者PyQuery等工具获取动态生成的登录token和相应cookie信息。
总结
本文简述了一个基于Python的火车票查询与购买小工具,其中包括两个主要的功能:火车票余票查询和火车票自动购买。通过以上代码示例,我们可以看到,Python作为一种全栈语言,在处理Web开发、网络编程和数据处理等方面都有其独特的优势,而在实现此类自动化工具方面,Python更是表现出其便捷和高效的特点。