网汽车票查询,有没有余票?,

返乡之路不容易之12306余票查询并给出备选方案

马上过年了,在外打工的游子终于要踏上返乡的旅程,尽管疫情严重,但家还是要回的,咱这离家远的一年到头只能回去一两次,想家呀!不说了,打开12306买票吧,我一看,果然没票了,这商务一等座咱也坐不起呀,这可咋整?

买不到直达的,咱要不多花点钱多买几站,或者先买票上车然后补票?

这个想法不错,那我首先得看每一趟车次的所有停靠站,然后再去搜有没有票。拿G3136这趟车来说,首发站是宁波,终点是太原南,那我只要出发站买在宁波到杭州东之间的任一站,终点站买在杭州东和太原南之间的任一站我就可以上车,一想到有办法回家了,心里还有点小激动。

一搜我就懵了,这么多的停靠站,出发站和到达站的排列组合那还不爆炸了?这得把我累死,回个家容易吗?

不对,咱是干啥的呀,鼓捣代码的,这种大量重复的工作交给它来干岂不是快哉,说干就干

此处省略一万字。。。

终于实现了!!!

只要输入出发地、目的地和出发时间,便能输出所有车次信息,有的车次能直接买,有的没法直接买,但是给出了备选,只要在备选中选一个就可以买到票回家喽。

代码如下:

# coding=utf-8import requestsimport urllib.parse as parseimport timeimport jsonimport pretty_errorsimport refrom fake_useragent import UserAgentTRAIN_NUMBER = 2TRAIN = 3DEPARTURE_STATION = 6TERMINUS = 7DEPARTURE_TIME = 8ARRIVAL_TIME = 9DURATION = 10IF_BOOK = 11DATE = 13NO_SEAT = 29HARD_SEAT = 28SOFT_SEAT = 27def Citys():    """    城市缩写    :return:    """    headers = {'User-Agent': str(UserAgent().random)}    url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9141'    content = requests.get(url=url, headers=headers)    content = content.content.decode('utf-8')    content = content    content_list = content.split('@')    dict_city = {}    for city in content_list:        str_1 = city        city_name = str_1  # 城市简称名        city_name_1 = str_1<:str_1.find('|')>  # 城市名        dict_city = city_name    return dict_citydef Time():    """    获取当前时间    :return:    """    list_time = list(time.localtime())    year = str(list_time<0>)    month = str(list_time<1>)    day = str(list_time<2>)    if len(month) == 1:        month = '0' + month    if len(day) == 1:        day = '0' + day    return year, month, dayproxy = {'http': '122.226.57.70:8888'}class Train:    def __init__(self,                 from_station,                 to_station,                 train_date=Time()<0> + '-' + Time()<1> + '-' + Time()<2>                 ):        self.from_station = from_station        self.to_station = to_station        self.train_date = train_date        self.url = 'https://kyfw.12306.cn/otn/leftTicket/queryA?leftTicketDTO.%s&leftTicketDTO.%s&leftTicketDTO.%s&purpose_codes=ADULT'        # self.headers = {        #     'Cookie': 'JSESSIONID=073CAA21150F40AA7F05551F7E1B5F5C; RAIL_DEVICEID=STuBhcdGH45k8StSkJVyk_v6qFnIUDpyzg1O9l7IyMoOPPIEEuBEqcBRuuv0WOKJrV4MdxGi08T0AzwlQ3d4guOQ6LTNlh7emO8TdgWZe2Wp3OuA9WIKYP5Ly-a3o-f5uHGmyX8yleCV0nzQDSL9grkJHRjA4syw; RAIL_EXPIRATION=1642644949013; guidesStatus=off; highContrastMode=defaltMode; cursorStatus=off; BIGipServerpool_index=804258314.43286.0000; route=6f50b51faa11b987e576cdb301e545c4; BIGipServerotn=384827914.24610.0000'}        self.headers = {'User-Agent': str(UserAgent().random)}        self.session = requests.session()        self.session.get(            'https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc&fs=%E6%9D%AD%E5%B7%9E%E4%B8%9C,HGH&ts=%E5%A4%AA%E5%8E%9F%E5%8D%97,TNV&date=2022-01-19&flag=N,N,Y',            headers=self.headers, proxies=proxy, timeout=5)    def station(self, train_number):        """        查找列车起点可买和终点可买        :return:        """        url = f'https://kyfw.12306.cn/otn/czxx/queryByTrainNo?' \              f'{parse.urlencode({"train_no": train_number})}&' \              f'{parse.urlencode({"from_station_telecode": Citys()})}&' \              f'{parse.urlencode({"to_station_telecode": Citys()})}&' \              f'{parse.urlencode({"depart_date": self.train_date})}'        self.headers<'User-Agent'> = str(UserAgent().random)        content = self.session.get(url, headers=self.headers, proxies=proxy, timeout=5)        # content = requests.get(url, headers=self.headers, proxies=proxy, timeout=5)        content = content.content.decode('utf-8')        data = json.loads(content)        stations_data = data<'data'><'data'>        stations_data.sort(key=lambda x: x<'station_no'>)        from_station_idx = int(            list(filter(lambda x: self.from_station in x<'station_name'>, stations_data))<0><'station_no'>)        from_station_buy =  for station in stations_data<:from_station_idx>>        to_station_buy =  for station in stations_data>        return from_station_buy, to_station_buy    def train(self):        """        爬取信息        :return:        """        url = self.url % (parse.urlencode({"train_date": self.train_date}),                          parse.urlencode({"from_station": Citys()}),                          parse.urlencode({"to_station": Citys()}))        self.headers<'User-Agent'> = str(UserAgent().random)        content = self.session.get(url, headers=self.headers, proxies=proxy, timeout=5)        # content = requests.get(url, headers=self.headers, proxies=proxy, timeout=5)        content = content.content.decode('utf-8')        data = json.loads(content)        dict_train = data<'data'><'result'>        dict_map = data<'data'><'map'>        res = <>        for train in dict_train:            train_split = train.split('|')            from_station_buy, to_station_buy = self.station(train_split)            buy = <>            for from_station, to_station in < for x in from_station_buy for y in to_station_buy>:                if train_split == 'N' and self.book_if(from_station, to_station, train_split):                    buy.append(f'{from_station}-{to_station}')            train_str = , dict_map>,                         dict_map>, train_split,                         train_split, train_split,                         '可以' if train_split == 'Y' else '不可以', ', '.join(buy)>            res.append('| ' + ' | '.join(train_str) + ' |')        return res    def book_if(self, from_station, to_station, train_number):        """        查询是否有票        :param from_station:        :param to_station:        :param train_number:        :return:        """        url = self.url % (parse.urlencode({"train_date": self.train_date}),                          parse.urlencode({"from_station": Citys()}),                          parse.urlencode({"to_station": Citys()}))        self.headers<'User-Agent'> = str(UserAgent().random)        content = self.session.get(url, headers=self.headers, proxies=proxy, timeout=5)        # content = requests.get(url, headers=self.headers, proxies=proxy, timeout=5)        content = content.content.decode('utf-8')        data = json.loads(content)        dict_train = data<'data'><'result'>        train = list(filter(lambda x: x.split('|') == train_number, dict_train))        if not train:            return        return True if train<0>.split('|') == 'Y' else Falseif __name__ == '__main__':    print('--------------------12306信息查询-----------------------')    while True:        from_station = input('请输入出发地:') or '杭州'        if from_station in Citys():            break    while True:        to_station = input('请输入目的地:') or '太原'        if to_station in Citys():            break    pattern = re.compile('\d{4}-\d{2}-\d{2}')    while True:        date = input('请输入出发时间(注意格式:2022-02-01, 默认情况下为购票当日):')        if not date or re.match(pattern, date):            break    if not date:        date = Time()<0> + '-' + Time()<1> + '-' + Time()<2>    train = Train(from_station, to_station, date)    #    information = train.train()    print('-------------------------------------------------------')    print('-------------------12306查询结果如下---------------------')    print('-------------------------------------------------------')    print('| 车次 | 出发站 | 到达站 | 出发时间 | 到达时间 | 历时 | 直接买 | 备选 |')    for info in information: print(info)    print('-------------------------------------------------------')

这是第一版的实现,目前还只是粗略地给出备选,省去大家手动搜索的时间,还有好多功能没有实现

  • 没有备选排名:虽然给出了备选,但哪个备选好一点没有给个排序
  • 没有座位信息(商务/一等/二等/硬座/无座):虽然能买,但是不一定能买到适合自己的(便宜的),有点奢侈了

能回家已经很开心了,准备实现第二版...

2024-03-13

后面没有了,返回>>电动车百科