def query_left_ticket(from_station, to_station, date): """ 查询余票 """ print '正在查询【%s】到【%s】的车票信息,请稍等...' % (from_station.encode('utf8'), to_station.encode('utf8')) station_code_map = query_station_code_map() if from_station not in station_code_map.keys(): print '未找到【%s】车站' % from_station return from_station = station_code_map[from_station] if to_station not in station_code_map.keys(): print u'未找到【%s】车站' % to_station return to_station = station_code_map[to_station] if date: date_pattern = re.compile(r'^\d{4}-\d{2}-\d{2}$') assert date_pattern.match(date), '乘车日期无效. %s' % date else: date = (datetime.date.today() + datetime.timedelta(days=1)).strftime('%Y-%m-%d') try_times = 3 while try_times > 0: try: trains = TrainInfoQueryAPI().info_query_left_tickets( date, from_station, to_station) break except Exception as e: pass try_times -= 1 else: print '网络请求失败,请重试...' return pt = prettytable.PrettyTable(field_names=[ '车次', '始发站', '目的站', '运行时间', '发车时间', '到达时间', '商务座', '一等座', '二等座', '软卧', '硬卧', '软座', '硬座', '无座', '备注' ], border=True) code_station_map = query_code_station_map() for train in trains: from_station = code_station_map[train['from_station']] to_station = code_station_map[train['to_station']] pt.add_row([ train['train_name'], from_station, to_station, train['duration'], train['departure_time'], train['arrival_time'], train[u'商务座'] or '--', train[u'一等座'] or '--', train[u'二等座'] or '--', train[u'软卧'] or '--', train[u'硬卧'] or '---', train[u'软座'] or '--', train[u'硬座'] or '--', train[u'无座'] or '--', train[u'remark'] or '--' ]) print pt
def query_station_code_map(): """ 信息查询-查询车站编码列表 :return JSON对象 """ station_code_map = {} stations = TrainInfoQueryAPI().info_query_station_list() for station in stations: station_code_map[station['name']] = station['code'] return station_code_map
def query_left_tickets(train_date, from_station, to_station, seat_types, train_names=None): """ 信息查询-剩余车票 :param train_date :param from_station :param to_station :param seat_types :param train_names :return JSON 对象 """ date_pattern = re.compile(r'^\d{4}-\d{2}-\d{2}$') assert date_pattern.match( train_date), 'Invalid train_date param. %s' % train_date assert isinstance(seat_types, list), u'Invalid seat_types param. %s' % seat_types assert frozenset(seat_types) <= frozenset(dict(SEAT_TYPE_CODE_MAP).keys( )), u'Invalid seat_types param. %s' % seat_types train_info = {} trains = TrainInfoQueryAPI().info_query_left_tickets( train_date, from_station, to_station) train_info, select_seat_type = _select_train_and_seat_type( train_names, seat_types, trains) if not train_info or not select_seat_type: raise exceptions.BookingTrainNoLeftTicket('无票') _logger.debug('select train info. %s' % json.dumps(train_info, ensure_ascii=False)) result = { 'train_date': train_date, 'from_station': train_info['from_station'], 'to_station': train_info['to_station'], 'seat_type': select_seat_type, 'seat_type_code': dict(SEAT_TYPE_CODE_MAP)[select_seat_type], 'departure_time': train_info['departure_time'], 'arrival_time': train_info['arrival_time'], 'secret': train_info['secret'], 'train_name': train_info['train_name'], 'duration': train_info['duration'], 'train_num': train_info['train_num'] } return result
# encoding: utf8 import json import pytest import urllib import datetime from hack12306 import exceptions from hack12306.query import TrainInfoQueryAPI from hack12306.utils import tomorrow, today from config import COOKIES train_info_query_api = TrainInfoQueryAPI() class TestTrainInfoQueryAPI(object): """ 测试12306信息查询API """ def test_info_query_station_trains(self): today_str = datetime.date.today().strftime('%Y-%m-%d') result = train_info_query_api.info_query_station_trains( today_str, 'LFV') assert isinstance(result, list) print json.dumps(result, ensure_ascii=False) def test_info_query_train_no(self): date_str = tomorrow().strftime('%Y-%m-%d') result = train_info_query_api.info_query_train_no( '24000000G505', 'VNP', 'SHH', date_str)
def test_order(): train_order_api = TrainOrderAPI() # 1. 查询剩余车票 train_date = tomorrow().strftime('%Y-%m-%d') result = TrainInfoQueryAPI().info_query_left_tickets( train_date, from_station, to_station) train_info = None for train in result: if train[constants.SEAT_TYPE_SECONDE_SEAT]: train_info = copy.deepcopy(train) train_info.update(train_date=train_date) print 'query left tickets result. %s' % json.dumps(train_info, ensure_ascii=False) # 2. 下单-提交订单 submit_order_result = train_order_api.order_submit_order( train_info['secret'], train_info['train_date'], cookies=COOKIES) print 'submit order result. %s' % submit_order_result # 3. 下单-确认乘客 confirm_passenger_result = train_order_api.order_confirm_passenger( cookies=COOKIES) print 'confirm passenger result. %s' % json.dumps( confirm_passenger_result, ensure_ascii=False, cls=JSONEncoder) # 4. 下单-检查订单信息 passengers = TrainUserAPI().user_passengers(cookies=COOKIES) passenger_info = passengers[0] passenger_ticket = gen_passenger_ticket_tuple( seat_type_code, passenger_info['passenger_flag'], passenger_info['passenger_type'], passenger_info['passenger_name'], passenger_info['passenger_id_type_code'], passenger_info['passenger_id_no'], passenger_info['mobile_no']) old_passenger = gen_old_passenge_tuple( passenger_info['passenger_name'], passenger_info['passenger_id_type_code'], passenger_info['passenger_id_no'], passenger_info['passenger_type']) passenger_ticket_str = ','.join(passenger_ticket) old_passenger_str = ','.join(old_passenger) check_order_result = train_order_api.order_confirm_passenger_check_order( confirm_passenger_result['token'], passenger_ticket_str, old_passenger_str, cookies=COOKIES) print 'check order result. %s' % json.dumps( check_order_result, ensure_ascii=False, cls=JSONEncoder) # 5. 下单-获取排队数量 queue_count_result = train_order_api.order_confirm_passenger_get_queue_count( train_info['train_date'], train_info['train_num'], seat_type_code, train_info['from_station'], train_info['to_station'], confirm_passenger_result['ticket_info']['leftTicketStr'], confirm_passenger_result['token'], confirm_passenger_result['order_request_params']['station_train_code'], confirm_passenger_result['ticket_info']['queryLeftTicketRequestDTO'] ['purpose_codes'], confirm_passenger_result['ticket_info']['train_location'], cookies=COOKIES, ) print 'confirm passenger get queue count result. %s' % json.dumps( queue_count_result, ensure_ascii=False, cls=JSONEncoder) if confirm_submit_order: # 6. 下单-确认车票 confirm_ticket_result = train_order_api.order_confirm_passenger_confirm_single_for_queue( passenger_ticket_str, old_passenger_str, confirm_passenger_result['ticket_info'] ['queryLeftTicketRequestDTO']['purpose_codes'], confirm_passenger_result['ticket_info']['key_check_isChange'], confirm_passenger_result['ticket_info']['leftTicketStr'], confirm_passenger_result['ticket_info']['train_location'], confirm_passenger_result['token'], cookies=COOKIES) print 'confirm passenger confirm ticket result. %s' % json.dumps( confirm_ticket_result, ensure_ascii=False, cls=JSONEncoder) # 7. 下单-查询订单 query_order_result = train_order_api.order_confirm_passenger_query_order( confirm_passenger_result['token']) print 'confirm passenger query order result. %s' % json.dumps( query_order_result, ensure_ascii=False, cls=JSONEncoder)