想查火车票信息的时候还在12306官网吗?或者打开手机里的APP?让我们使用Python编写火车票查看器的命令行版本。你只需要在命令行敲一行就可以得到你想要的火车票信息!如果您刚刚接触Python的基础知识,这是一个不错的小练习。界面设计应用程序是为他人使用而编写的,即使它仅供您自己使用。所以,首先,你应该想好你要如何使用它?让我们先给这个小应用程序起个名字。既然是用来查询票务信息的,那我们就叫tickets吧。我们希望用户只要输入出发站、到达站和日期就可以得到他们想要的信息,所以车票应该这样使用:$ticketsfromtodate另外还有各种火车,高铁,动车,express,fastanddirect,我们希望能提供一个选项,只查询一种或几种列车,所以我们应该有如下选项:-g高铁-d子弹头列车-texpress-kexpress-zdirect这些选项应该是可以组合使用的,所以,最后我们的接口应该是这样的:$tickets[-gdtkz]fromtodate接口已经确定了,剩下的就是实现它了。在开发环境中编写Python程序的一个好习惯是使用工具virtualenv创建一个虚拟环境。我们的程序是使用Python3开发的。接下来,在你的工作目录下创建一个文件夹tickets,进去创建一个虚拟环境:$virtualenv-p/usr/bin/python3venv用下面的命令激活它:$.venv/bin/activate解析参数Python有很多工具可以用来编写命令行应用程序,比如argparse、docopt、options...这里,我们选择docopt这个简单易用的工具,我们先安装它:$pip3installdocoptdocopt可以在文档中定义字符串格式来解析参数,在tickets.py中:#coding:utf-8"""Trainticketsqueryviacommand-line.Usage:tickets[-gdtkz]Options:-h,--helpDisplayhelpMenu-gHigh-speedrail-dMotiontrain-tExpress-kExpress-z直接示例:ticketsNanjingBeijing2016-07-01tickets-dgNanjingBeijing2016-07-01"""fromdocoptimportdocoptdefcli():"""command-lineinterface"""arguments=docopt(__doc__)print(arguments)if__name__=='__main__':cli()现在让我们运行这个程序:$python3tickets.pyShanghaiBeijing2016-07-01我们得到如下参数解析r结果:{'-d':False,'-g':False,'-k':False,'-t':False,'-z':False,'':'2016-07-01','':'Shanghai','':'Beijing'}数据获取参数已经解析完毕,下面就是如何获取数据,也是最重要的部分。首先,我们打开12306,进入余票查询页面。如果使用chrome,按F12打开开发者工具,选择网络栏,在查询框中输入上海到北京,日期为2016-07-01。点击查询,我们调试工具发现查询系统实际请求的是这个URLhttps://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate=2016-07-01&from_station=SHH&to_station=BJP返回数据为JSON格式!那么问题就简单了,我们只需要构造请求URL,然后解析返回的JSON数据即可。但是我们发现url中的from_station和to_station不是汉字,而是一个代码,而用户输入的是汉字,我们如何获取代码呢?我们打开网页的源代码,看看有没有什么发现。啊哈!果然,我们在网页中找到了这个链接:点我,里面好像有所有站的中文名称、拼音、简称和代号,我们在项目目录下保存为stations.html。但是信息挤在一起,我们只想要中文名字和大写字母的代码信息,怎么办?答对了!正则表达式,我们写一个小脚本来匹配和提取想要的信息,在parse.py中:#coding:utf-8importrefrompprintimportpprintwithopen('stations.html','r')asf:text=f.read()stations=re.findall(u'([\u4e00-\u9fa5]+)|([A-Z]+)',text)pprint(dict(stations),indent=4)我们运行这个脚本,它将以Returnallstationsand他们的大写字母代码以字典的形式出现,我们将结果重定向到stations.py,$python3parse.py>stations.py我们向这个字典添加一个名称,stations,最后,stations.py文件如下所示:stations={'一一宝':'YJT','一点边坡':'YPB',...'龙镇':'LZA','龙谷店':'LGM'}现在,用户输入站的中文名称,我们可以直接从这个字典中获取它的字母代码:...fromstationsimportstationsdefcli():arguments=docopt(__doc__)from_staion=stations.get(arguments[''])to_station=stations。get(arguments[''])date=arguments['']#BuildURLurl='https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate={}&from_station={}&to_station={}'.format(date,from_staion,to_station)万事俱备,我们请求这个URL获取数据吧!这里我们使用requests库,先安装它:$pip3installrequests它提供了一个非常简单易用的接口,...importrequestsdefcli():...#Addverify=False参数,不验证证书r=requests.get(url,verify=False)print(r.json())从结果我们可以观察到需要进一步提取与票证相关的信息:defcli():...r=requsets.get(url);rows=r.json()['data']['datas']说明结果数据已经拿到了,剩下的就是提取我们想要的信息和在prettytable库中显示它允许我们像MySQL数据库一样格式化和显示数据。$pip3installprettytable可以这样使用:...fromprettytableimportPrettyTabledefcli():...headers='车次,到站时间,商务一等座,二等座软卧,硬卧,软座,硬座,无座'。split()pt=PrettyTable()pt._set_field_names(headers)forrowinrows:#根据headers从row中过滤信息,然后调用pt.add_row()添加到table中...print(pt)练习下面的问题是留给大家练习:根据headers过滤每一行的信息,将结果添加到prettytable1.将出发站和到达站,出发时间和到达时间显示为一列,如开始图2.添加颜色(提示:使用colorama,termcorlororANSIescapecharacters)3.添加异常处理,如果用户输入的站或日期错误怎么办?网络异常怎么办?...4。增加更多日期格式支持:例如用户也可以输入20181020进行搜索。5.增加参数支持,用户可以指定列车类型