Pythonでコマンドライン版の列車チケットビューアを実現

5549 ワード

インタフェースせっけい
一つのアプリは最終的に人に使うように書かれています.たとえ自分で使っても.だから、まずどうやって使いたいか考えてみましょう.まず、このアプリに名前をつけましょう.チケット情報を調べる以上、ticketsと呼んでください.私たちはユーザーが出発駅、到着駅、日付を入力すれば希望の情報を得ることができることを望んでいるので、ticketsはこのように使用されるべきです.

$ tickets from to date

また、列車には様々なタイプがあり、高速鉄道、列車、特急、快速、直通があります.特定の列車の1つまたはいくつかだけを検索するオプションを提供することを望んでいます.そのため、次のオプションがあります.
     -g高速鉄道
     -d動車
     -t特急
     -k快速
     -z直通
これらのオプションは組み合わせて使用できるはずです.そのため、最終的には私たちのインタフェースはこのようになります.

$ tickets [-gdtkz] from to date

インタフェースはすでに確定しており、残りはそれを実現することです.
開発環境
Pythonプログラムを書く良い実践はvirtualenvというツールを使って仮想環境を構築することです.私たちのプログラムはPython 3を使用して開発され、次はあなたの作業ディレクトリの下にフォルダ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を使うならば、F 12を押して开発者のツールを开いて、Networkの1栏を选んで、検索の枠の时计で私达は上海を入力して北京に着いて、日付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_stationto_stationは漢字ではなく、代号であり、ユーザーが入力したのは漢字であることがわかりました.私たちはどのように代号を取得しますか?Webソースを開いて、何か発見があるかどうか見てみましょう.
ああ!やはり、私たちはホームページの中でこのリンクを見つけました:私をクリックします.この中にはすべての駅の中国語名、ピンイン、略語、代名詞などの情報が含まれているようで、私たちはプロジェクトカタログの下で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の勉強に役立つことを望んでいます.