Maison >développement back-end >Tutoriel Python >Python implémente le système de requête de billets de train 12306
Récemment, j'ai vu que Python était utilisé pour implémenter la requête de billets de train, je l'ai également implémenté moi-même et j'ai senti que j'avais beaucoup gagné. Je partagerai chaque étape en détail ci-dessous. (Notez que python3 est utilisé)
Je vais d'abord montrer le résultat final :
Exécuter sur la ligne de commande cmd : python tickets.py -dk shanghai chengdu 20161007 > txt
signifie : interrogez les informations sur le train commençant par D et K de Shanghai à Chengdu le 07/10/2016 et enregistrez-les dans le fichier result.txt ; .txt Les résultats dans le fichier :
Voici les étapes de mise en œuvre :
1. Installer des bibliothèques tierces pip install Installation : request, docopt, Prettytable
2. docopt peut être utilisé pour analyser les paramètres saisis à partir de la ligne de commande :
""" Usage: test [-gdtkz] <from> <to> <date> Options: -h,--help 显示帮助菜单 -g 高铁 -d 动车 -t 特快 -k 快速 -z 直达 Example: tickets -gdt beijing shanghai 2016-08-25 """ import docopt args = docopt.docopt(__doc__) print(args) # 上面 """ """ 包含中的: #Usage: # test [-gdtkz] <from> <to> <date> #是必须要的 test 是可以随便写的,不影响解析Le résultat final imprimé est un dictionnaire pour une utilisation ultérieure :
3. Obtenez des informations sur le train
Notre interface pour interroger les votes restants en 12306 : url : 'https://kyfw.12306.cn/otn/resources/js/framework/station_name. js? station_version=1.8968'La méthode est : getParamètres transmis : queryDate:2016-10-05, from_station:CDW, to_station:SHHL'abréviation correspondante de la ville est Une autre interface est nécessaire pour interroger pour obtenir 3.1 Interroger l'abréviation de la ville : L'url de cette interface = 'https://kyfw.12306.cn/otn /resources/js/framework/ station_name.js?station_version=1.8968' La méthode est get Utilisez des expressions régulières sur les résultats renvoyés pour obtenir le nom de la ville et les valeurs de l'abréviation (les valeurs renvoyées sont). similaire : 7@cqn|Chongqing South|CRW|chongqingnan|cqn |, ce dont nous avons besoin est : CRW, chongqingnan), le code est le suivant parse_stations.py :
#coding=utf-8 from prettytable import PrettyTable class TrainCollection(object): """ 解析列车信息 """ # 显示车次、出发/到达站、 出发/到达时间、历时、一等坐、二等坐、软卧、硬卧、硬座 header = '序号 车次 出发站/到达站 出发时间/到达时间 历时 商务座 一等座 二等座 软卧 硬卧 硬座 无座'.split() def __init__(self,rows,traintypes): self.rows = rows self.traintypes = traintypes def _get_duration(self,row): """ 获取车次运行的时间 """ duration = row.get('lishi').replace(':','小时') + '分' if duration.startswith('00'): return duration[4:] elif duration.startswith('0'): return duration[1:] return duration @property def trains(self): result = [] flag = 0 for row in self.rows: if row['station_train_code'][0] in self.traintypes: flag += 1 train = [ # 序号 flag, # 车次 row['station_train_code'], # 出发、到达站点 '/'.join([row['from_station_name'],row['to_station_name']]), # 成功、到达时间 '/'.join([row['start_time'],row['arrive_time']]), # duration 时间 self._get_duration(row), # 商务座 row['swz_num'], # 一等座 row['zy_num'], # 二等座 row['ze_num'], # 软卧 row['rw_num'], # 硬卧 row['yw_num'], # 硬座 row['yz_num'], # 无座 row['wz_num'] ] result.append(train) return result def print_pretty(self): """打印列车信息""" pt = PrettyTable() pt._set_field_names(self.header) for train in self.trains: pt.add_row(train) print(pt) if __name__ == '__main__': t = TrainCollection()Le module pprint peut Il s'agit d'informations imprimées, plus faciles à lire : Exécuter dans cmd : python parse_stations.py > 🎜> obtiendra le fichier stations.py dans le répertoire courant, dans le fichier C'est le nom et l'abréviation du site. Ajoutez "stations = " au fichier stations.py pour créer un dictionnaire afin de faciliter la sélection ultérieure des valeurs. est le contenu du fichier stations.py :
3.2 Maintenant que les paramètres d'obtention des informations sur le train sont prêts, l'étape suivante consiste à obtenir la valeur de retour du train et analysez les informations dont vous avez besoin, telles que : le numéro de train, le nombre de billets en première classe, etc. . , myprettytable.py
#coding=utf-8 from prettytable import PrettyTable class TrainCollection(object): """ 解析列车信息 """ # 显示车次、出发/到达站、 出发/到达时间、历时、一等坐、二等坐、软卧、硬卧、硬座 header = '序号 车次 出发站/到达站 出发时间/到达时间 历时 商务座 一等座 二等座 软卧 硬卧 硬座 无座'.split() def __init__(self,rows,traintypes): self.rows = rows self.traintypes = traintypes def _get_duration(self,row): """ 获取车次运行的时间 """ duration = row.get('lishi').replace(':','小时') + '分' if duration.startswith('00'): return duration[4:] elif duration.startswith('0'): return duration[1:] return duration @property def trains(self): result = [] flag = 0 for row in self.rows: if row['station_train_code'][0] in self.traintypes: flag += 1 train = [ # 序号 flag, # 车次 row['station_train_code'], # 出发、到达站点 '/'.join([row['from_station_name'],row['to_station_name']]), # 成功、到达时间 '/'.join([row['start_time'],row['arrive_time']]), # duration 时间 self._get_duration(row), # 商务座 row['swz_num'], # 一等座 row['zy_num'], # 二等座 row['ze_num'], # 软卧 row['rw_num'], # 硬卧 row['yw_num'], # 硬座 row['yz_num'], # 无座 row['wz_num'] ] result.append(train) return result def print_pretty(self): """打印列车信息""" pt = PrettyTable() pt._set_field_names(self.header) for train in self.trains: pt.add_row(train) print(pt) if __name__ == '__main__': t = TrainCollection()prettytable Cette bibliothèque peut imprimer un format similaire à l'affichage des données de requête MySQL,
4. L'étape suivante consiste à intégrer les différents modules : tickets.py
"""Train tickets query via command-line. Usage: tickets [-gdtkz] <from> <to> <date> Options: -h,--help 显示帮助菜单 -g 高铁 -d 动车 -t 特快 -k 快速 -z 直达 Example: tickets -gdt beijing shanghai 2016-08-25 """ import requests from docopt import docopt from stations import stations # from pprint import pprint from myprettytable import TrainCollection class SelectTrain(object): def __init__(self): """ 获取命令行输入的参数 """ self.args = docopt(__doc__)#这个是获取命令行的所有参数,返回的是一个字典 def cli(self): """command-line interface""" # 获取 出发站点和目标站点 from_station = stations.get(self.args['<from>']) #出发站点 to_station = stations.get(self.args['<to>']) # 目的站点 leave_time = self._get_leave_time()# 出发时间 url = 'https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate={0}&from_station={1}&to_station={2}'.format( leave_time,from_station,to_station)# 拼接请求列车信息的Url # 获取列车查询结果 r = requests.get(url,verify=False) traindatas = r.json()['data']['datas'] # 返回的结果,转化成json格式,取出datas,方便后面解析列车信息用 # 解析列车信息 traintypes = self._get_traintype() views = TrainCollection(traindatas,traintypes) views.print_pretty() def _get_traintype(self): """ 获取列车型号,这个函数的作用是的目的是:当你输入 -g 是只是返回 高铁,输入 -gd 返回动车和高铁,当不输参数时,返回所有的列车信息 """ traintypes = ['-g','-d','-t','-k','-z'] # result = [] # for traintype in traintypes: # if self.args[traintype]: # result.append(traintype[-1].upper()) trains = [traintype[-1].upper() for traintype in traintypes if self.args[traintype]] if trains: return trains else: return ['G','D','T','K','Z'] def _get_leave_time(self): """ 获取出发时间,这个函数的作用是为了:时间可以输入两种格式:2016-10-05、20161005 """ leave_time = self.args['<date>'] if len(leave_time) == 8: return '{0}-{1}-{2}'.format(leave_time[:4],leave_time[4:6],leave_time[6:]) if '-' in leave_time: return leave_time if __name__ == '__main__': cli = SelectTrain() cli.cli()D'accord, c'est en gros ce que je fais. a dit au début, vous pouvez interroger les informations sur le train que vous souhaitez Ce qui précède est le script Python introduit par l'éditeur pour implémenter le système de requête de billets de train 12306. J'espère qu'il sera utile à tout le monde si vous l'avez fait. Si vous avez des questions, veuillez me le faire savoir. Laissez un message et l'éditeur vous répondra à temps. Je voudrais également vous remercier tous pour votre soutien au site Web PHP chinois ! Pour plus d'articles liés à l'implémentation Python du système de demande de billets de train 12306, veuillez faire attention au site Web PHP chinois !