亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

利用Python實現命令行版的火車票查看器

系統 1530 0

接口設計

一個應用寫出來最終是要給人使用的,哪怕只是給你自己使用。所以,首先應該想想你希望怎么使用它?讓我們先給這個小應用起個名字吧,既然及查詢票務信息,那就叫它 tickets 好了。我們希望用戶只要輸入出發站,到達站以及日期就讓就能獲得想要的信息,所以 tickets 應該這樣被使用:

            
$ tickets from to date
          

另外,火車有各種類型,高鐵、動車、特快、快速和直達,我們希望可以提供選項只查詢特定的一種或幾種的火車,所以,我們應該有下面這些選項:

???? -g 高鐵

???? -d 動車

???? -t 特快

???? -k 快速

???? -z 直達

這幾個選項應該能被組合使用,所以,最終我們的接口應該是這個樣子的:

            
$ tickets [-gdtkz] from to date
          

接口已經確定好了,剩下的就是實現它了。

開發環境

寫Python程序的一個良好實踐是使用 virtualenv 這個工具建一個虛擬的環境。我們的程序使用Python3開發,下面在你的工作目錄下建一個文件夾 tickets ,進去創建一個虛擬環境:

            
$ virtualenv -p /usr/bin/python3 venv
          

通過下面的命令激活它:

            
$ . venv/bin/activate
          

解析參數

Python有很多寫命令行應用的工具,如 argparse, docopt, options …這里,我們選用 docopt 這個簡單易用的工具,我們先安裝它:

            
$ pip3 install docopt
          

docopt 可以按我們在文檔字符串中定義的格式來解析參數,在 tickets.py 中:

            
# coding: utf-8

"""Train tickets query via command-line.

Usage:
  tickets [-gdtkz] 
            
              
                
                  

Options: 
  -h,--help    顯示幫助菜單
  -g        高鐵
  -d        動車
  -t        特快
  -k        快速
  -z        直達

Example:
  tickets 南京 北京 2016-07-01
  tickets -dg 南京 北京 2016-07-01
"""
from docopt import docopt

def cli():
  """command-line interface""" 
  arguments = docopt(__doc__)
  print(arguments)

if __name__ == '__main__': 
  cli()
                
              
            
          

下面我們運行一下這個程序:

            
$ python3 tickets.py 上海 北京 2016-07-01
          

我們得到下面的參數解析結果:

            
{‘-d': False, ‘-g': False, ‘-k': False, ‘-t': False, ‘-z': False, ‘
            
              ': ‘2016-07-01', ‘
              
                ': ‘上海', ‘
                
                  ': ‘北京'}
                
              
            
          

獲取數據

參數已經解析好了,下面就是如何獲取數據了,這也是最主要的部分。首先我們打開12306,進入余票查詢頁面,如果你使用chrome,那么按F12打開開發者工具,選中Network一欄,在查詢框鐘我們輸入上海到北京,日期2016-07-01, 點擊查詢,我們在調試工具發現,查詢系統實際上請求了這個URL

            
https://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 。但是這些信息擠在一起,而我們只想要中文名和大寫字母的代號信息,怎么辦呢?

BINGO!正則表達式,我們寫個小腳本來匹配提取出想要的信息吧, 在 parse.py 中:

            
# coding: utf-8
import re
from pprint import pprint

with open('stations.html', 'r') as f:
  text = f.read()
  stations = re.findall(u'([\u4e00-\u9fa5]+)\|([A-Z]+)', text)
  pprint(dict(stations), indent=4)
          

我們運行這個腳本,它將以字典的形式返回所有車站和它的大寫字母代號, 我們將結果重定向到 stations.py 中,

            
$ python3 parse.py > stations.py
          

我們為這個字典加名字, stations , 最終, stations.py 文件是這樣的:

            
stations = {  
  '一間堡': 'YJT',
  '一面坡': 'YPB',
   ... 
  '龍鎮': 'LZA',
  '龍骨甸': 'LGM'
}
          

現在,用戶輸入車站的中文名,我們就可以直接從這個字典中獲取它的字母代碼了:

            
...
from stations import stations

def cli():
  arguments = docopt(__doc__)
  from_staion = stations.get(arguments['
            
              '])
  to_station = stations.get(arguments['
              
                '])
  date = arguments['
                
                  ']
  # 構建URL
  url = 'https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate={}&from_station={}&to_station={}'.format(
    date, from_staion, to_station
)
                
              
            
          

萬事俱備,下面我們來請求這個URL獲取數據吧!這里我們使用 requests 這個庫, 先安裝它:

            
$ pip3 install requests
          

它提供了非常簡單易用的接口,

            
...
import requests

def cli():
  ...
  # 添加verify=False參數, 不驗證證書
  r = requests.get(url, verify=False)
  print(r.json())
          

從結果中,我們可以觀察到,與車票有關的信息需要進一步提取:

            
def cli():
  ...
  r = requsets.get(url);
  rows = r.json()['data']['datas']
          

顯示結果

數據已經獲取到了,剩下的就是提取我們要的信息并將它顯示出來。 prettytable 這個庫可以讓我們它像MySQL數據庫那樣格式化顯示數據。

            
$ pip3 install prettytable
          

這樣使用它:

            
...
from prettytable import PrettyTable

def cli():
  ...
  headers = '車次 車站 時間 歷時 商務 一等 二等 軟臥 硬臥 軟座 硬座 無座'.split()
  pt = PrettyTable()
  pt._set_field_names(headers)
  for row in rows:
  # 從row中根據headers過濾信息, 然后調用pt.add_row()添加到表中
    ...
  print(pt)
          

總結

以上就是用Python寫一個命令行版的火車票查看器的全部內容,對于Python學習是個不錯的例子,希望能對大家學習Python有所幫助。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 四虎影院在线播放视频 | 亚洲欧美国产毛片在线 | 天天上天天操 | 国产成人久久精品一区二区三区 | 男人深夜网站 | 日日噜噜夜夜狠狠tv视频免费 | 一本色道久久爱88av俺来也 | 天天综合色天天综合网 | 亚洲综合在线观看一区www | 天天干国产 | videos欧美丰满肥婆 | 亚洲成a人片在线观看精品 亚洲成a人一区二区三区 | 午夜免费福利网站 | 天天插夜夜操 | 青青青国产在线 | 欧美整片在线 | 欧美视频在线一区 | 99久久精品国产交换 | 99视频网站 | 亚洲高清在线视频 | 粗大猛烈进出呻吟声的视频 | 欧美国产日产精品免费视频 | 99re久久在热线播放最新地址 | 亚洲精品久久一区影院 | 99精品欧美一区二区三区 | 亚洲第一伊人 | 日韩中文字幕久久精品 | 亚洲干综合 | 四虎精品免费国产成人 | 国产在线中文字幕 | 日韩一区二区三区在线视频 | 四虎国产精品永久免费网址 | 亚洲一区二区三区高清视频 | 99精品国产成人一区二区在线 | 妖精视频一区二区三区 | 欧日韩一区二区三区 | 欧美日韩综合 | 日操操 | 99re在线这里只有精品 | 欧美xxx69╳xxhd | 美女嗯啊 |