澳门新浦京娱乐场网站-www.146.net-新浦京娱乐场官网
做最好的网站

携程机票查询,查询类继承关系

以前参考别人的代码,用Python做了一个12306命令行式的火车票查询工具,感觉还挺有意思的!于是自己又做了一个类似的——携程机票查询器。

一、requests等库的介绍

requests:发送请求,获取响应内容

docopt:命令行解析工具,可以根据自定义的语法格式,自动生成解析器

prettytable:使用表格形式打印数据

colorama:命令行着色

诞生之初用来作为配置管理语言的Python,现在已经成为最流行的编程语言之一,尤其是随着AI应用的兴起,变得无处不在。

作者:Vamei 出处: 欢迎转载,也请保留这段声明。谢谢!

图片 1

携程官网查询的效果是这样的:

二、开发环境搭建

image.png

 

首先看看如何快速查看剩余火车票?

图片 2

下载Python2的安装文件[windows版]

https://www.python.org/

Python中的getoptoptparse模块都可以进行命令行程序的开发,不过它们已经被废弃,在2.7和3.2版本中引入了argparse模块;这里介绍使用argparser模块,只需要数十行代码,就可以做出漂亮的命令行程序。

在这里列举一些我使用Python时积累的小技巧。这些技巧是我在使用Python过程中经常使用的。之前很零碎的记在笔记本中,现在整理出来,和大家分享,也作为Python快速教程的一个补充。

当你想查询一下火车票信息的时候,你还在上12306官网吗?或是打开你手机里的APP?下面让我们来用Python写一个命令行版的火车票查看器, 只要在命令行敲一行命令就能获得你想要的火车票信息!如果你刚掌握了Python基础,这将是个不错的小练习。这篇文章分享之前我还是要推荐下我自己的Python学习交流群:617327703,不定期分享干货,包括我自己整理的一份2018最新的Python资料和零基础入门教程,欢迎各位小伙伴。

Python命令行界面查询的效果是这样的:

安装Python2

此处省略N个字

1.基本的命令行

看看官方文档里的一个示例:

def main():
    parser = argparse.ArgumentParser(description='Process some integers.')
    parser.add_argument('integers', metavar='N', type=int, nargs=' ',
                    help='an integer for the accumulator')
    parser.add_argument('--sum', dest='accumulate', action='store_const',
                    const=sum, default=max,
                    help='sum the integers (default: find the max)')

    args = parser.parse_args()
    print args.accumulate(args.integers)

这几行代码实现的功能为:
如果命令行输入不带--sum选项,则对输入的多个整数执行max操作;否则,执行sum操作。例如:
在命令行中执行:
python prog.py 1 2 3 4
输出为:4

在命令行中执行:
python prog.py 1 2 3 4 --sum
输出为:10

上面的代码中,主要的过程分为三个步骤:

  • 调用argparse.ArgumentParser的构造器创建一个ArgumentParser对象。
  • 调用ArgumentParseradd_argument()方法添加命令行的参数,包括可选参数和必选参数。其中以---开头的表示可选参数,其它的表示必须输入的参数。
  • 调用parser.parse_args()方法对传入的sys.argv参数进行解析。

 

接口设计

图片 3

配置环境变量

修改环境变量Path,追加Python2的安装路径[C:Python27]

图片 4

image

2.实现子命令

有时候,我们可以根据功能将命令行分组成一系列相关的子命令。例如,Git命令行可以分为以下几组:

These are common Git commands used in various situations:

start a working area (see also: git help tutorial)
   clone      Clone a repository into a new directory
   init       Create an empty Git repository or reinitialize an existing one

work on the current change (see also: git help everyday)
   add        Add file contents to the index
   mv         Move or rename a file, a directory, or a symlink
   reset      Reset current HEAD to the specified state
   rm         Remove files from the working tree and from the index

examine the history and state (see also: git help revisions)
   bisect     Find by binary search the change that introduced a bug
   grep       Print lines matching a pattern
   log        Show commit logs
   show       Show various types of objects
   status     Show the working tree status

grow, mark and tweak your common history
   branch     List, create, or delete branches
   checkout   Switch branches or restore working tree files
   commit     Record changes to the repository
   diff       Show changes between commits, commit and working tree, etc
   merge      Join two or more development histories together
   rebase     Forward-port local commits to the updated upstream head
   tag        Create, list, delete or verify a tag object signed with GPG

collaborate (see also: git help workflows)
   fetch      Download objects and refs from another repository
   pull       Fetch from and integrate with another repository or a local branch
   push       Update remote refs along with associated objects

在Python中,利用argparse模块也可以很容易做出这样的子命令行程序。

例如,我们要做一个对用户信息进行管理的命令行程序,包括添加、删除、查询显示等几个功能。

我们可以根据功能将其分为三个子命令:add,delete,show。

相应的代码可以这样写:

def main():
    parser = argparse.ArgumentParser(prog='cmd')

    sub_parser = parser.add_subparsers(title='subcommands',
                                    description='valid subcommands',
                                    help='config subscommand help')

    add_parser = sub_parser.add_parser('add',help='add user config')
    add_parser.add_argument('--name', required=True, help='user name')
    add_parser.add_argument('--addr', required=False, help='user address')
    add_parser.add_argument('--phone', required=False, help='phone number')
    add_parser.set_defaults(func=add_fn)

    delete_parser = sub_parser.add_parser('delete', help='delete user config')
    delete_parser.add_argument('--name', required=True, help='user name')
    delete_parser.set_defaults(func=delete_fn)

    show_parser = sub_parser.add_parser('show', help='show user config')
    show_parser.set_defaults(func=show_fn)

    args = parser.parse_args()
    args.func(args)

对上面的代码进行概要的解释:ArgumentParser对象的add_subparsers()方法创建了一个特殊的action实例,对这个实例分别调用add_parser()方法来创建子命令对应的ArgumentParser,再调用这个ArgumentParser实例的add_argument()方法来添加子命令的参数。
一个比较方便的地方在于,可以通过ArgumentParserset_defaults()方法来设置子命令对应的处理函数。上面的示例中,分别为三个子命令设置了处理函数:add_fndelete_fnshow_fn

在命令行程序中执行:
python cmd.py --help,将显示出以下信息:

usage: 
    cmd [sub-command]

optional arguments:
  -h, --help         show this help message and exit

subcommands:
  valid subcommands

  {add,delete,show}  config subscommand help
    add              add user config
    delete           delete user config
    show             show user config

从帮助信息中可以看到,命令行被组织为三个子命令,分别为adddeleteshow

在命令行中执行:
python cmd.py add --help,可以查看add子命令的帮助信息:

usage: cmd [sub-command] add [-h] --name NAME [--addr ADDR]
                                    [--phone PHONE]

optional arguments:
  -h, --help     show this help message and exit
  --name NAME    user name
  --addr ADDR    user address
  --phone PHONE  phone number

对于add子命令,它有3个参数,分别为用户名、联系地址、电话号码;其中用户名为必选参数,其它两个为可选参数。

在命令行中执行:
python cmd.py add --name 'Eric' --addr 'California,USA' --phone '0076938377'`

添加一个User的处理逻辑将由add_fn()来完成。程序中将得到一个信息为{name='Eric',addr='California,USA', phone='0076938377'}的User。

def add_fn(args):
    args_dict = vars(args)

    name = args_dict['name']
    address = args_dict['addr']
    phone_number = args_dict['phone']

    print 'Add User : %-10s s s' % (name, address, phone_number)
    ...

其它的deleteshow子命令与此类似,不再赘述。

import模块

在Python经常使用import声明,以使用其他模块(也就是其它.py文件)中定义的对象。

1) 使用__name__

当我们编写Python库模块的时候,我们往往运行一些测试语句。当这个程序作为库被import的时候,我们并不需要运行这些测试语句。一种解决方法是在import之前,将模块中的测试语句注释掉。Python有一种更优美的解决方法,就是使用__name__。

下面是一个简单的库程序TestLib.py。当直接运行TestLib.py时,__name__为"__main__"。如果被import的话,__name__为"TestLib"。

图片 5

def lib_func(a):
    return a   10

def lib_func_another(b):
    return b   20

if __name__ == '__main__':
    test = 101
    print(lib_func(test))

图片 6

 我们在user.py中import上面的TestLib。

import TestLib
print(TestLib.lib_func(120))

 你可以尝试不在TestLib.py中使用if __name__=='__main__', 并对比运行结果。

 

2) 更多import使用方式

import TestLib as test         # 引用TestLib模块,并将它改名为t

比如:

import TestLib as t
print(t.lib_func(120))

from TestLib import lib_func   # 只引用TestLib中的lib_func对象,并跳过TestLib引用字段

这样的好处是减小所引用模块的内存占用。

比如:

from TestLib import lib_func
print(lib_func(120))

from TestLib import *          # 引用所有TestLib中的对象,并跳过TestLib引用字段

比如:

from TestLib import *
print(lib_func(120))

 

一个应用写出来最终是要给人使用的,哪怕只是给你自己使用。所以,首先应该想想你希望怎么使用它?让我们先给这个小应用起个名字吧,既然及查询票务信息,那就叫它tickets好了。我们希望用户只要输入出发站,到达站以及日期就让就能获得想要的信息,所以tickets应该这样被使用:

输入出发地、目的地、乘机日期,即可看到可选的航班、机场、出发到达时间、票价等信息。

检查环境是否正常

图片 7

image

3.小结

使用Python的argparse模块,短短的几十行代码就可以搭建起来一个命令行程序的骨架。

argparse模块中最重要的是ArgumentParser对象,它包含了以下几个方法:

  • add_argument()
  • add_subparsers()
  • parse_args()

关于这几个方法的用法,以及参数的详细的说明请参考官方文档。

查询

1) 查询函数的参数

当我们想要知道某个函数会接收哪些参数的时候,可以使用下面方法查询。

import inspect
print(inspect.getargspec(func))

 

2) 查询对象的属性

除了使用dir()来查询对象的属性之外,我们可以使用下面内置(built-in)函数来确认一个对象是否具有某个属性:

hasattr(obj, attr_name)   # attr_name是一个字符串

例如:

a = [1,2,3]
print(hasattr(a,'append'))

 

2) 查询对象所属的类和类名称

a = [1, 2, 3]
print a.__class__
print a.__class__.__name__

 

3) 查询父类

我们可以用__base__属性来查询某个类的父类:

cls.__base__

例如:

print(list.__base__)

 

$ tickets from to date

程序的源码如下:

给eclipse工具安装Aptana插件

图片 8

image

使用中文(以及其它非ASCII编码)

在Python程序的第一行加入#coding=utf8,例如:

#coding=utf8
print("你好吗?")

也能用以下方式:

#-*- coding: UTF-8 -*-
print("你好吗?")

 

另外,火车有各种类型,高铁、动车、特快、快速和直达,我们希望可以提供选项只查询特定的一种或几种的火车,所以,我们应该有下面这些选项:

1.air_stations.py

配置eclipse

设置python解释器的路径[C:Python27python.exe]

图片 9

image

表示2进制,8进制和16进制数字

在2.6以上版本,以如下方式表示

print(0b1110)     # 二进制,以0b开头
print(0o10)       # 八进制,以0o开头
print(0x2A)       # 十六进制,以0x开头

如果是更早版本,可以用如下方式:

print(int("1110", 2))
print(int("10", 8))
print(int("2A", 16))

 

-g 高铁

2.airline_ticket.py

三、安装相关的库

注释

一行内的注释可以以#开始

多行的注释可以以'''开始,以'''结束,比如

图片 10

'''
This is demo
'''

def func():
    # print something
    print("Hello world!")  # use print() function

# main
func()

图片 11

注释应该和所在的程序块对齐。

 

-d 动车

 1 #1.air_stations.py
 2 import re
 3 import os
 4 import json
 5 import requests
 6 from pprint import pprint
 7 
 8 url = 'http://webresource.c-ctrip.com/code/cquery/resource/address/flight/flight_new_poi_gb2312.js?CR_2017_07_18_00_00_00'
 9 response = requests.get(url,verify=False)
10 station = re.findall(u'([u4e00-u9fa5] )(([A-Z] ))', response.text)
11 stations = dict(station)
12 pprint(stations,indent = 4)

 1 2.airline_ticket.py
 2 #此程序可用于查询携程机票,查询需要指定出发日期、出发城市、目的城市!(模仿了12306火车订票查询程序)Python学习群 125240963 每天更新学习资料、进群获取数十套PDF电子书
 3 import requests,json,os
 4 from docopt import docopt
 5 from prettytable import PrettyTable
 6 from colorama import init,Fore
 7 from air_stations import stations
 8 
 9 fromCity = input('Please input the city you want leave :')
10 toCity = input('Please input the city you will arrive :')
11 tripDate = input('Please input the date(Example:2017-09-27) :')
12 
13 init()
14 class TrainsCollection:
15     header = '航空公司 航班 机场 时间 机票价格 机场建设费'.split()
16     def __init__(self,airline_tickets):
17         self.airline_tickets = airline_tickets
18 
19     @property
20     def plains(self):
21         #航空公司的总表没有找到,但是常见航空公司也不是很多就暂时用这个dict{air_company}来收集!
22         #如果strs没有查询成功,则会返回一个KeyError,表示此dict中未找到目标航空公司,则会用其英文代码显示!
23         air_company = {"G5":"华夏航空","9C":"春秋航空","MU":"东方航空","NS":"河北航空","HU":"海南航空","HO":"吉祥航空","CZ":"南方航空","FM":"上海航空","ZH":"深圳航空","MF":"厦门航空","CA":"中国国航","KN":"中国联航"}
24         for item in self.airline_tickets:
25             try:
26                 strs = air_company[item['alc']]
27             except KeyError:
28                 strs = item['alc']
29             airline_data = [
30             Fore.BLUE   strs   Fore.RESET,
31             Fore.BLUE   item['fn']   Fore.RESET,
32             'n'.join([Fore.YELLOW   item['dpbn']   Fore.RESET,
33                        Fore.CYAN   item['apbn']   Fore.RESET]),
34             'n'.join([Fore.YELLOW   item['dt']   Fore.RESET,
35                        Fore.CYAN   item['at']   Fore.RESET]),
36             item['lp'],
37             item['tax'],
38             ]
39             yield airline_data
40 
41     def pretty_print(self):
42         #PrettyTable()用于在屏幕上将查询到的航班信息表逐行打印到终端
43         pt = PrettyTable()
44         pt._set_field_names(self.header)
45         for airline_data in self.plains:
46             pt.add_row(airline_data)
47         print(pt)
48 
49 def doit():
50     headers = {
51         "Cookie":"自定义",
52         "User-Agent": "自定义",
53         }
54     arguments = {
55     'from':fromCity,
56     'to':toCity,
57     'date':tripDate
58     }
59     DCity1 = stations[arguments['from']]
60     ACity1 = stations[arguments['to']]
61     DDate1 = arguments['date']
62     url = ("http://flights.ctrip.com/domesticsearch/search/SearchFirstRouteFlights?DCity1={}&ACity1={}&SearchType=S&DDate1={}").format(DCity1,ACity1,DDate1)
63     try:
64         r = requests.get(url,headers = headers,verify=False)
65     except Exception as e:
66         print(repr(e))
67     print(url)
68     airline_tickets = r.json()['fis']
69     TrainsCollection(airline_tickets).pretty_print()
70 
71 if __name__ == '__main__':
72     doit()

安装requests库

图片 12

image

搜索路径

当我们import的时候,Python会在搜索路径中查找模块(module)。比如上面import TestLib,就要求TestLib.py在搜索路径中。

我们可以通过下面方法来查看搜索路径:

import sys
print(sys.path)

我们可以在Python运行的时候增加或者删除sys.path中的元素。另一方面,我们可以通过在shell中增加PYTHONPATH环境变量,来为Python增加搜索路径。

下面我们增加/home/vamei/mylib到搜索路径中:

$export PYTHONPATH=$PYTHONPATH:/home/vamei/mylib

你可以将正面的这行命令加入到~/.bashrc中。这样,我们就长期的改变了搜索路径。

 

-t 特快

其实,此小程序还可以拓展,譬如将查询记录存到本地电脑(txt格式、或者存到数据库里)或者更厉害的还可以设置定时自动查询;还可以设置查询到自动发邮箱提醒;还可以用Python的GUI库将此程序做成桌面软件的形式。。。。

安装docopt库

pip install docopt

脚本与命令行结合

可以使用下面方法运行一个Python脚本,在脚本运行结束后,直接进入Python命令行。这样做的好处是脚本的对象不会被清空,可以通过命令行直接调用。

$python -i script.py

 

-k 快速

 

安装prettytable库

pip install prettytable

安装非标准包

Python的标准库随着Python一起安装。当我们需要非标准包时,就要先安装。

1) 使用Linux repository (Linux环境)

这是安装Python附加包的一个好的起点。你可以在Linux repository中查找可能存在的Python包 (比如在Ubuntu Software Center中搜索matplot)。

2) 使用pip。pip是Python自带的包管理程序,它连接Python repository,并查找其中可能存在的包。

比如使用如下方法来安装、卸载或者升级web.py:

$pip install web.py

$pip uninstall web.py

$pip install --upgrade web.py

如果你的Python安装在一个非标准的路径(使用$which python来确认python可执行文件的路径)中,比如/home/vamei/util/python/bin中,你可以使用下面方法设置pip的安装包的路径:

$pip install --install-option="--prefix=/home/vamei/util/" web.py

3) 从源码编译

如果上面方法都没法找到你想要的库,你可能需要从源码开始编译。Google往往是最好的起点。

-z 直达

学点编程,好处多多

本文由澳门新浦京娱乐场网站发布于www.146.net,转载请注明出处:携程机票查询,查询类继承关系