Exemple #1
0
 def __get_substations(self, train):
     # Gets stations in (train.departure, train.destination]
     url = "https://kyfw.12306.cn/otn/czxx/queryByTrainNo"
     params = self.__get_train_data_query_params(train)
     json = webrequest.get_json(url, params=params)
     json_station_list = json["data"]["data"]
     logger.debug("Fetched station data for train " + train.name)
     istart = None
     iend = len(json_station_list)
     for i in range(len(json_station_list)):
         is_in_path = json_station_list[i]["isEnabled"]
         if is_in_path and istart is None:
             istart = i
         elif not is_in_path and istart is not None:
             iend = i
             break
     assert istart is not None
     assert json_station_list[istart]["station_name"] == train.departure_station.name
     assert json_station_list[iend-1]["station_name"] == train.destination_station.name
     available_stations = []
     station_list = StationList.instance()
     for i in range(istart+1, iend-1):
         station_name = json_station_list[i]["station_name"]
         if self.station_blacklist[station_name]:
             continue
         station = station_list.get_by_name(station_name)
         available_stations.append(station)
     available_stations.append(train.destination_station)
     return available_stations
Exemple #2
0
 def execute(self):
     url = "https://kyfw.12306.cn/otn/leftTicket/query"
     params = self.__get_query_params()
     json = webrequest.get_json(url, params=params)
     try:
         json_data = json["data"]
     except RequestError as ex:
         if ex.args[0] == "选择的查询日期不在预售日期范围内":
             raise DateOutOfRangeError() from ex
         raise
     logger.debug("Got train list from {0} to {1} on {2}".format(
         self.departure_station.name,
         self.destination_station.name,
         timeconverter.date_to_str(self.date)))
     train_list = []
     station_list = StationList.instance()
     for train_data in json_data:
         query_data = train_data["queryLeftNewDTO"]
         departure_station = station_list.get_by_id(query_data["from_station_telecode"])
         destination_station = station_list.get_by_id(query_data["to_station_telecode"])
         if self.exact_departure_station and departure_station != self.departure_station:
             continue
         if self.exact_destination_station and destination_station != self.destination_station:
             continue
         train = Train(train_data, departure_station, destination_station, self.pricing, self.date)
         train_list.append(train)
     return train_list
Exemple #3
0
def autobuy():
    # Get station list
    station_list = StationList.instance()
    cookies = SessionCookies()

    # Login beforehand (just in case!)
    # TODO: Allow multiple logins
    try:
        login_manager = login(cookies, retry=True, auto=True)
    except SystemMaintenanceError:
        # Stupid website goes offline every night for "maintenance".
        print(localization.SYSTEM_OFFLINE)
        return None

    retry_search = config.get("search_retry", True)
    while True:
        # Search for train
        train_list = query(station_list, retry=retry_search, auto=True)
        if train_list is None:
            # No trains found and retry is False
            return None

        # Purchase tickets
        try:
            train = select_train(train_list, auto=True)
            return purchase(cookies, train, auto=True)
        except UnfinishedTransactionError:
            # TODO: Change an account if possible?
            print(localization.UNFINISHED_TRANSACTIONS)
            return None
        except DataExpiredError:
            # This means the user waited too long between
            # querying train data and submitting the order.
            # We simply re-query the train list and try again.
            train_list = query(station_list, retry_search, auto=True)
            train = select_train(train_list, auto=True)
            return purchase(cookies, train, auto=True)
        except NotEnoughTicketsError:
            # Tickets ran out while we tried to purchase
            # Just jump back to the beginning of the loop
            # and try again.
            pass

    login_manager.logout()