快捷搜索:  汽车  科技

12306显示余票数量(返乡之路不容易之12306余票查询并给出备选方案)

12306显示余票数量(返乡之路不容易之12306余票查询并给出备选方案)代码如下:只要输入出发地、目的地和出发时间,便能输出所有车次信息,有的车次能直接买,有的没法直接买,但是给出了备选,只要在备选中选一个就可以买到票回家喽。不对,咱是干啥的呀,鼓捣代码的,这种大量重复的工作交给它来干岂不是快哉,说干就干此处省略一万字。。。终于实现了!!!

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

12306显示余票数量(返乡之路不容易之12306余票查询并给出备选方案)(1)

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

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

12306显示余票数量(返乡之路不容易之12306余票查询并给出备选方案)(2)

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

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

此处省略一万字。。。

终于实现了!!!

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

12306显示余票数量(返乡之路不容易之12306余票查询并给出备选方案)(3)

代码如下:

# coding=utf-8 import requests import urllib.parse as parse import time import json import pretty_errors import re from fake_useragent import UserAgent TRAIN_number = 2 TRAIN = 3 DEPARTURE_STATION = 6 TERMINUS = 7 DEPARTURE_TIME = 8 ARRIVAL_TIME = 9 DURATION = 10 IF_BOOK = 11 DATE = 13 NO_SEAT = 29 HARD_SEAT = 28 SOFT_SEAT = 27 def 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.find('=') 2:-2] content_list = content.split('@') dict_city = {} for city in content_list: str_1 = city[city.find('|') 1:] city_name = str_1[str_1.find('|') 1:str_1.find('|') 4] # 城市简称名 city_name_1 = str_1[:str_1.find('|')] # 城市名 dict_city[city_name_1] = city_name return dict_city def 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 day proxy = {'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=杭州东 HGH&ts=太原南 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()[self.from_station]})}&' \ f'{parse.urlencode({"to_station_telecode": Citys()[self.to_station]})}&' \ 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 = [station['station_name'] for station in stations_data[:from_station_idx]] to_station_buy = [station['station_name'] for station in stations_data[from_station_idx:]] 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()[self.from_station]}) parse.urlencode({"to_station": Citys()[self.to_station]})) 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[TRAIN_NUMBER]) buy = [] for from_station to_station in [[x y] for x in from_station_buy for y in to_station_buy]: if train_split[IF_BOOK] == 'N' and self.book_if(from_station to_station train_split[TRAIN]): buy.append(f'{from_station}-{to_station}') train_str = [train_split[TRAIN] dict_map[train_split[DEPARTURE_STATION]] dict_map[train_split[TERMINUS]] train_split[DEPARTURE_TIME] train_split[ARRIVAL_TIME] train_split[DURATION] '可以' if train_split[IF_BOOK] == '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()[from_station]}) parse.urlencode({"to_station": Citys()[to_station]})) 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] == train_number dict_train)) if not train: return return True if train[0].split('|')[IF_BOOK] == 'Y' else False if __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('-------------------------------------------------------')


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

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

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

猜您喜欢: