1. 知识点:
- Python 基础知识的综合运用
- docopt, requests, colorama, prettytable 库的使用
2 requests: 使用Python访问HTTP资源的必备库
prettytable: 可以将打印内容格式化为像MySQL一样的输出
docopt:命令行参数解析工具
colorama: 命令行着色工具
3.
解析参数
docopt模块可以按照我们自己在文档字符串定义的格式来解析参数,如下
# -*- coding:utf-8 -*-
"""命令行火车票查看器
Usage:
tickets [-gdtkz] <from> <to> <date>
Options:
-h,--help 显示帮助菜单
-g 高铁
-d 动车
-t 特快
-k 快速
-z 直达
Example:
tickets 太原 北京 2019-06-12
tickets -dg 天津 南昌 2019-06-10
"""
arguments = docopt(__doc__)
由上面的程序中,docopt会根据我们在docstring中定义的格式解析参数并返回一个字典(arguments)
-tk 北京 太原 2019-06-10
{'-d': False,
'-g': False,
'-k': True,
'-t': True,
'-z': False,
'<date>': '2019-06-10',
'<from>': '北京',
'<to>': '太原'}
2. 获取数据
参数解析好以后,我们可以通过12306官网获取我们需要的数据,IE浏览器打开12306官网的查票系统,输入出发地,目的地,日期,查询,通过F12开发者模式找到请求地址(刷新一次):
(图片上传出错,后续补)
通过此请求URL,我们可以看到有我们需要的信息,或者直接点击参数查看:
可以看到参数为:出发地 查询类型(成人,学生) 日期 目的地
通过正文可以看到:返回一个json格式的数据,即一个字典,里边包括了各个站点的中文名和站点代号,我们可以利用这个接口来获取。
打开此页的源码(在页面右击选择查看源码):
查看一下具体内容:
复制此链接前边需要加一级域名https://kyfw.12306.cn打开, 如下:
https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8971
可以得到有关stations的信息
station_names是一个很长的字符串,里边包括了所有车站中文名,拼音,简写,代号等,这里可以看到有很多信息,我们提取我们需要的信息中文字母和代号信息,我们用正则表达式来提取:
写一个简单的脚本抓取(parse_station.py):
import re
import requests
from pprint import pprint
url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8994'
response = requests.get(url, verify=False) # verify=False不验证证书
stations = re.findall(u'([\u4e00-\u9fa5]+)+\|([A-Z]+)', response.text)
pprint(dict(stations), indent=4)
将提取的有关地点的信息重定向到stations.py文件中
stations = { '一间堡': 'YJT',
'一面坡': 'YPB',
'一面坡北': 'YXB',
'一面山': 'YST',
'七台河': 'QTB',
'七甸': 'QDM',
'七营': 'QYJ',
'七里河': 'QLD',
'万乐': 'WEB',
'万发屯': 'WFB',
'万宁': 'WNQ',
'万州': 'WYW',
'万州北': 'WZE',
'万年': 'WWG',
'万源': 'WYY',
'三义井': 'OYD',
'三井子': 'OJT',
'三亚': 'SEQ',
'三元区': 'SMS',
'三关口': 'OKJ',
'三十家': 'SRD',
'三十里堡': 'SST',
'三原': 'SAY',
'三合庄': 'SVP',
'三堂集': 'SDH',
'三家寨': 'SMM',
'三家店': 'ODP',
'三明': 'SVS',
'三明北': 'SHS',
'三水': 'SJQ',
'三水北': 'ARQ',
'三水南': 'RNQ',
'三汇镇': 'OZW',
'三江南': 'SWZ',
'三江县': 'SOZ',
'三江口': 'SKD',
'三河县': 'OXP',
'三源浦': 'SYL',
'三穗': 'QHW',
'三营': 'OEJ',
'三道湖': 'SDL',
'三都县': 'KKW',
'三门县': 'OQH',
'三门峡': 'SMF',
'三门峡南': 'SCF',
'三门峡西': 'SXF',
'三间房': 'SFX',
'三阳': 'SYU',
'三阳川': 'SYJ',
'上万': 'SWP',
'上园': 'SUD',
'上杭': 'JBS',
'上板城': 'SBP',
'上板城南': 'OBP',
'上海': 'SHH',
'上海南': 'SNH',
'上海虹桥': 'AOH',
'上海西': 'SXH',
'上腰墩': 'SPJ',
'上虞': 'BDH',
'上西铺': 'SXM',
'上饶': 'SRG',
'上高镇': 'SVK',
'下台子': 'EIP',
'下城子': 'XCB',
'下板城': 'EBP',
'下社': 'XSV',
'下花园': 'XYP',
'下马塘': 'XAT',
'世博园': 'ZWT',
'东': 'FDC',
'东丰': 'DIL',
'东乡': 'DXG',
'东二道河': 'DRB',
'东京城': 'DJB',
'东光': 'DGP',
'东升': 'DRQ',
'东台': 'DBH',
'东城南': 'IYQ',
'东安东': 'DCZ',
'东岔': 'DCJ',
'东庄': 'DZV',
'东戌': 'RXP',
'东戴河': 'RDD',
'东方': 'UFQ',
'东方红': 'DFB',
'东明县': 'DNF',
'东明村': 'DMD',
'东来': 'RVD',
'东津': 'DKB',
'东海': 'DHB',
'东海县': 'DQH',
'东淤地': 'DBV',
'东港北': 'RGT',
'东湾': 'DRJ',
'东胜': 'DOC',
'东胜东': 'RSC',
'东胜西': 'DYC',
'东至': 'DCH',
'东莞': 'RTQ',
'东莞东': 'DMQ',
'东营': 'DPK',
'东营南': 'DOK',
'东辛庄': 'DXD',
'东边井': 'DBB',
'东通化': 'DTL',
'东镇': 'DNV',
'两家': 'UJT',
'两当': 'LDY',
'中华门': 'VNH',
'中卫': 'ZWJ',
'中和': 'ZHX',
'中宁': 'VNJ',
'中宁东': 'ZDJ',
'中宁南': 'ZNJ',
'中寨': 'ZZM',
'中山': 'ZSQ',
'中山北': 'ZGQ',
'中川机场': 'ZJJ',
'中牟': 'ZGF',
'丰乐镇': 'FZB',
'丰城': 'FCG',
'丰城南': 'FNG',
'丰水村': 'FSJ',
'丰都': 'FUW',
'丰镇': 'FZC',
'丰顺': 'FUQ',
'临城': 'UUP',
'临川': 'LCG',
'临江': 'LQL',
'临汾': 'LFV',
'临汾西': 'LXV',
'临沂': 'LVK',
'临沂东': 'UYK',
'临河': 'LHC',
'临泽': 'LEJ',
'临泽南': 'LDJ',
'临海': 'UFH',
'临淄北': 'UEK',
'临清': 'UQK',
'临湘': 'LXQ',
'临澧': 'LWQ',
'临西': 'UEP',
'临邑': 'LUK',
'临颍': 'LNF',
'临高南': 'KGQ',
'丹东': 'DUT',
'丹东西': 'RWT',
'丹凤': 'DGY',
'丹徒': 'RUH',
'丹阳': 'DYH',
'丹阳北': 'EXH',
'丹霞山': 'IRQ',
'丽水': 'USH',
'丽江': 'LHM',
'乃林': 'NLD',
'义乌': 'YWH',
'义县': 'YXD',
'义县西': 'YSD',
'义马': 'YMF',
'乌伊岭': 'WPB',
'乌兰哈达': 'WLC',
'乌兰察布': 'WPC',
'乌兰木图': 'VLT',
'乌兰浩特': 'WWT',
'乌奴耳': 'WRX',
'乌尔旗汗': 'WHX',
'乌拉山': 'WSC',
'乌拉特前旗': 'WQC',
'乌海': 'WVC',
'乌海西': 'WXC',
'乌苏': 'WSR',
'乌西': 'WXR',
'乌鲁木齐': 'WAR',
'乌鲁木齐南': 'WMR',
'乌龙泉南': 'WFN',
'乐东': 'UQQ',
'乐善村': 'LUM',
'乐山': 'IVW',
'乐山北': 'UTW',
'乐平市': 'LPG',
'乐昌': 'LCQ',
'乐昌东': 'ILQ',
'乐清': 'UPH',
'乐都': 'LDO',
'乐都南': 'LVO',
'九三': 'SSX',
'九台': 'JTL',
'九台南': 'JNL',
'九江': 'JJG',
'九郎山': 'KJQ',
'乳山': 'ROK',
'乾县': 'QBY',
'乾安': 'QOT',
'二密河': 'RML',
'二营': 'RYJ',
'二连': 'RLC',
'二道沟门': 'RDP',
'二道湾': 'RDX',
'二龙': 'RLD',
'二龙山屯': 'ELA',
'于都': 'YDG',
'云东海': 'NAQ',
'云南驿': 'ANM',
'云居寺': 'AFP',
'云山': 'KZQ',
'云彩岭': 'ACP',
'云梦': 'YMN',
'云浮东': 'IXQ',
'云霄': 'YBS',
'五五': 'WVR',
'五原': 'WYC',
'五叉沟': 'WCT',
'五台山': 'WSV',
'五大连池': 'WRB',
'五女山': 'WET',
'五家': 'WUB',
'五寨': 'WZV',
'五常': 'WCB',
'五府山': 'WFG',
'五棵树': 'WKT',
'五莲': 'WLK',
'五营': 'WWB',
'五通': 'WTZ',
'五道沟': 'WDL',
'五道河': 'WHP',
'五龙背': 'WBT',
'五龙背东': 'WMT',
'井冈山': 'JGG',
'井南': 'JNP',
'井店': 'JFP',
'井陉': 'JJP',
'亚': 'JUQ',
'亚布力': 'YBB',
'亚布力南': 'YWB',
'亚布力西': 'YSB',
'亚龙湾': 'TWQ',
'交城': 'JNV',
'京山': 'JCN',
'亭亮': 'TIZ',
'亮甲店': 'LRT',
'亳州': 'BZH',
'什里店': 'OMP',
'仁布': 'RUO',
'介休': 'JXV',
'介休东': 'JDV',
'从江': 'KNW',
'仙人桥': 'XRL',
'仙林': 'XPH',
'仙桃西': 'XAN',
'仙游': 'XWS',
'代县': 'DKV',
'仪征': 'UZH',
'仲恺': 'KKQ',
'任丘': 'RQP',
'伊图里河': 'YEX',
'伊宁': 'YMR',
'伊宁东': 'YNR',
'伊尔施': 'YET',
'伊拉哈': 'YLX',
'伊敏': 'YMX',
'伊春': 'YCB',
'伊林': 'YLB',
'伊通': 'YTL',
'会同': 'VTQ',
'会昌北': 'XEG',
'低庄': 'DVQ',
'低窝铺': 'DWJ',
'余姚': 'YYH',
'余姚北': 'CTH',
'余杭': 'EVH',
'余江': 'YHG',
'余粮堡': 'YLD',
'佛坪': 'FUY',
'佛山': 'FSQ',
'佛山西': 'FOQ',
'佳木斯': 'JMB',
'佳木斯西': 'JUB',
'依兰': 'YEB',
'依安': 'YAX',
'侯马': 'HMV',
'侯马西': 'HPV',
'保定': 'BDP',
'保定东': 'BMP',
'保康': 'BKD',
'信丰': 'EFG',
'信宜': 'EEQ',
'信阳': 'XUN',
'信阳东': 'OYN',
'修文县': 'XWE',
'修武': 'XWF',
'修武西': 'EXF',
'倭肯': 'WQB',
'偃师': 'YSF',
'偏岭': 'PNT',
'偏店': 'PRP',
'元宝山': 'YUD',
'元氏': 'YSP',
'元谋': 'YMM',
'先锋': 'NQQ',
'光山': 'GUN',
'光明城': 'IMQ',
'光泽': 'GZS',
'克一河': 'KHX',
'克东': 'KOB',
'克山': 'KSB',
'克拉玛依': 'KHR',
'免渡河': 'MDX',
'兑镇': 'DWV',
'兖州': 'YZK',
'全州南': 'QNZ',
'全椒': 'INH',
'八仙筒': 'VXD',
'八方山': 'FGQ',
'八步': 'BBE',
'八角台': 'BTD',
'八达岭': 'ILP',
'八里甸子': 'BLT',
'八面城': 'BMD',
'八面通': 'BMB',
'公主岭': 'GLT',
'公主岭南': 'GBT',
'公庙子': 'GMC',
'公营子': 'GYD',
'六合': 'KLH',
'六合镇': 'LEX',
'六安': 'UAH',
'六枝': 'LIW',
'六盘山': 'UPJ',
'六盘水': 'UMW',
'六道河子': 'LVP',
'兰岗': 'LNB',
'兰州': 'LZJ',
'兰州东': 'LVJ',
'兰州新区': 'LQJ',
'兰州西': 'LAJ',
'兰棱': 'LLB',
'兰溪': 'LWH',
'兰考': 'LKF',
'兰考南': 'LUF',
'兰陵北': 'COK',
'共青城': 'GAG',
'关岭': 'GLE',
'关林': 'GLF',
'兴业': 'SNZ',
'兴义': 'XRZ',
'兴凯': 'EKB',
'兴和西': 'XEC',
'兴国': 'EUG',
'兴城': 'XCD',
'兴宁': 'ENQ',
'兴安': 'XAZ',
'兴安北': 'XDZ',
'兴平': 'XPY',
'兴泉堡': 'XQJ',
'兴隆县': 'EXP',
'兴隆店': 'XDD',
'兴隆镇': 'XZB',
'内乡': 'NXF',
'内江': 'NJW',
'内江北': 'NKW',
'册亨': 'CHZ',
'冕宁': 'UGW',
'军粮城北': 'JMP',
'农安': 'NAT',
'冠豸山': 'GSS',
'冯屯': 'FTX',
'冷水江东': 'UDQ',
'准格尔': 'ZEC',
'凌海': 'JID',
'凌源': 'LYD',
'凌源东': 'LDD',
'凤凰城': 'FHT',
'凤凰机场': 'FJQ',
'凤县': 'FXY',
'凤城东': 'FDT',
'凤州': 'FZY',
'凤阳': 'FUH',
'凭祥': 'PXZ',
'凯里': 'KLW',
'凯里南': 'QKW',
'刀尔登': 'DRD',
'分宜': 'FYG',
'刘家店': 'UDT',
'刘家河': 'LVT',
'创业村': 'CEX',
'利川': 'LCN',
'利津南': 'LNK',
'到保': 'RBT',
'前卫': 'QWD',
'前山': 'QXQ',
'前磨头': 'QMP',
'前苇塘': 'QWP',
'前进镇': 'QEB',
'前锋': 'QFB',
'剑门关': 'JME',
'加格达奇': 'JGX',
'勃利': 'BLB',
'勉县': 'MVY',
'包头': 'BTC',
'包头东': 'BDC',
'化州': 'HZZ',
'化德': 'HGC',
'北井子': 'BRT',
'北京': 'BJP',
'北京东': 'BOP',
'北京北': 'VAP',
'北京南': 'VNP',
'北京西': 'BXP',
'北台': 'BTT',
'北宅': 'BVP',
'北安': 'BAB',
'北屯': 'BYP',
'北屯市': 'BXR',
'北戴河': 'BEP',
'北流': 'BOZ',
'北海': 'BHZ',
'北滘': 'IBQ',
'北碚': 'BPW',
'北票': 'BPT',
'北票南': 'RPD',
'北营': 'BIV',
'北马圈子': 'BRP',
'十堰': 'SNN',
'十家子': 'SJD',
'十渡': 'SEP',
'千岛湖': 'QDU',
'千河': 'QUY',
'千阳': 'QOY',
'午汲': 'WJP',
'华城': 'VCQ',
'华家': 'HJT',
'华容': 'HRN',
'华容东': 'HPN',
'华容南': 'KRN',
'华山': 'HSY',
'华山北': 'HDY',
'华蓥': 'HUW',
'卓资东': 'ZDC',
'卓资山': 'ZZC',
'南': 'FXS',
'南丰': 'NFG',
'南丹': 'NDZ',
'南京': 'NJH',
'南京南': 'NKH',
'南仇': 'NCK',
'南充': 'NCW',
'南充北': 'NCE',
'南关岭': 'NLT',
'南华': 'NAM',
'南华北': 'NHS',
'南博山': 'NBK',
'南口': 'NKP',
'南口前': 'NKT',
'南召': 'NAF',
'南台': 'NTT',
'南城': 'NDG',
'南城司': 'NSP',
'南堡北': 'TLP',
'南大庙': 'NMP',
'南头': 'NOQ',
'南宁': 'NNZ',
'南宁东': 'NFZ',
'南宁西': 'NXZ',
'南宫东': 'NFP',
'南岔': 'NCB',
'南峪': 'NUP',
'南平': 'NPS',
'南平北': 'NBS',
'南平南': 'NNS',
'南昌': 'NCG',
'南昌西': 'NXG',
'南曹': 'NEF',
'南朗': 'NNQ',
'南木': 'NMX',
'南杂木': 'NZT',
'南桥': 'NQD',
'南江': 'FIW',
'南江口': 'NDQ',
'南河川': 'NHJ',
'南湖东': 'NDN',
'南湾子': 'NWP',
'南翔北': 'NEH',
'南芬': 'NFT',
'南芬北': 'NUT',
'南观村': 'NGP',
'南通': 'NUH',
'南部': 'NBE',
'南阳': 'NFF',
'南阳寨': 'NYF',
'南陵': 'LLH',
'南雄': 'NCQ',
'南靖': 'NJS',
'博乐': 'BOR',
'博克图': 'BKX',
'博兴': 'BXK',
'博白': 'BBZ',
'博鳌': 'BWQ',
'卢龙': 'UAP',
'卧里屯': 'WLX',
'卫东': 'WVT',
'卫星': 'WVB',
'卫辉': 'WHF',
'即墨北': 'JVK',
'原平': 'YPV',
'原平西': 'IPV',
'厦门': 'XMS',
'厦门北': 'XKS',
'厦门高崎': 'XBS',
'友好': 'YOB',
'双丰': 'OFB',
'双吉': 'SML',
'双城北': 'SBB',
'双城堡': 'SCB',
'双峰北': 'NFQ',
'双水镇': 'PQQ',
'双河镇': 'SEL',
'双洋': 'SQS',
'双流机场': 'IPW',
'双流西': 'IQW',
'双牌': 'SBZ',
'双辽': 'ZJD',
'双阳': 'OYT',
'双鸭山': 'SSB',
'双龙湖': 'OHB',
'发耳': 'FEM',
'口东': 'KEQ',
'口前': 'KQL',
'古东': 'GDV',
'古交': 'GJV',
'古北口': 'GKP',
'古城镇': 'GZB',
'古浪': 'GLJ',
'古田': 'G