Created
October 6, 2018 11:32
-
-
Save weaming/ad7d75e8f871bff3c82fa2cb6e5a2863 to your computer and use it in GitHub Desktop.
途牛火车票
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# coding: utf-8 | |
""" | |
Author : weaming | |
Created Time : 2018-10-06 18:04:41 | |
从途牛接口获取火车信息 | |
https://github.com/jokermonn/-Api/blob/master/TuniuTickets.md | |
""" | |
import json | |
from datetime import datetime | |
import requests | |
url = "http://huoche.tuniu.com/yii.php" | |
def get_url_text(url, json=False, params=None): | |
res = requests.get(url, params=params) | |
if res.status_code == 200: | |
if json: | |
return res.json() | |
return res.text | |
else: | |
raise Exception("Unexpected response code {}".format(res.status_code)) | |
def get_data(args): | |
""" | |
type AutoGenerated struct { | |
Code int `json:"code"` | |
Data struct { | |
Count int `json:"count"` | |
CrossURL interface{} `json:"crossURL"` | |
Expire bool `json:"expire"` | |
Filter struct { | |
Filter []struct { | |
ID string `json:"id"` | |
Name string `json:"name"` | |
Pros []struct { | |
ID int `json:"id"` | |
Name string `json:"name"` | |
} `json:"pros"` | |
} `json:"filter"` | |
Sort []struct { | |
ID int `json:"id"` | |
Name string `json:"name"` | |
Type int `json:"type"` | |
} `json:"sort"` | |
} `json:"filter"` | |
FreshURL interface{} `json:"freshUrl"` | |
IsFinish interface{} `json:"isFinish"` | |
LastTime int64 `json:"lastTime"` | |
List []struct { | |
AccessByIdcard string `json:"accessByIdcard"` | |
ArrivalCityCode int `json:"arrivalCityCode"` | |
ArrivalCityName string `json:"arrivalCityName"` | |
CanChooseSeat int `json:"canChooseSeat"` | |
DepartDepartTime string `json:"departDepartTime"` | |
DepartStationID int `json:"departStationId"` | |
DepartStationName string `json:"departStationName"` | |
DepartStationType int `json:"departStationType"` | |
DepartStationTypeName string `json:"departStationTypeName"` | |
DepartureCityCode int `json:"departureCityCode"` | |
DepartureCityName string `json:"departureCityName"` | |
DestArriveTime string `json:"destArriveTime"` | |
DestStationID int `json:"destStationId"` | |
DestStationName string `json:"destStationName"` | |
DestStationType int `json:"destStationType"` | |
DestStationTypeName string `json:"destStationTypeName"` | |
Duration int `json:"duration"` | |
DurationDay int `json:"durationDay"` | |
DurationStr string `json:"durationStr"` | |
Memo string `json:"memo"` | |
Prices []interface{} `json:"prices"` | |
SaleStatus int `json:"saleStatus"` | |
SellOut int `json:"sellOut"` | |
StartSaleTime string `json:"startSaleTime"` | |
TrainID int `json:"trainId"` | |
TrainNum string `json:"trainNum"` | |
TrainStartDate string `json:"trainStartDate"` | |
TrainType int `json:"trainType"` | |
TrainTypeName string `json:"trainTypeName"` | |
UpOrDown int `json:"upOrDown"` | |
} `json:"list"` | |
Origin interface{} `json:"origin"` | |
Remark interface{} `json:"remark"` | |
ReserveUrls interface{} `json:"reserveUrls"` | |
Stores interface{} `json:"stores"` | |
StreamID interface{} `json:"streamId"` | |
TrainTypeDetails []struct { | |
Number int `json:"number"` | |
TrainType int `json:"trainType"` | |
TrainTypeName string `json:"trainTypeName"` | |
} `json:"trainTypeDetails"` | |
UnsureStores interface{} `json:"unsureStores"` | |
} `json:"data"` | |
} | |
""" | |
params = { | |
"r": "train/trainTicket/getTickets", | |
"primary[departureDate]": args.date, | |
"primary[departureCityName]": args.start, | |
"primary[arrivalCityName]": args.end, | |
"start": args.offset, | |
"limit": args.limit, | |
} | |
data = get_url_text(url, params=params, json=True) | |
return data | |
station_code = { | |
"北京": "200", | |
"郑州": "1202", | |
"广州": "602", | |
"南京": "1602", | |
"西安": "2702", | |
"上海": "2500", | |
"深圳": "619", | |
"徐州": "1620", | |
"重庆": "300", | |
"天津": "3000", | |
"武汉": "1402", | |
"成都": "2802", | |
"哈尔滨": "1102", | |
"东莞": "606", | |
"株洲": "1515", | |
"沈阳": "1902", | |
"济南": "2402", | |
"洛阳": "1210", | |
"厦门": "414", | |
"青岛": "2413", | |
"乌鲁木齐": "3102", | |
"阿克苏": "3103", | |
"安康": "2703", | |
"安陆": "41476", | |
"安庆": "103", | |
"鞍山": "1903", | |
"安顺": "803", | |
"安阳": "1203", | |
"白城": "1803", | |
"保定": "1003", | |
"宝鸡": "2704", | |
"包头": "2104", | |
"鲅鱼圈": "40453", | |
"巴中": "2803", | |
"北戴河": "40043", | |
"北海": "704", | |
"蚌埠": "104", | |
"博乐": "42624", | |
"苍南": "40788", | |
"沧州": "1005", | |
"长春": "1802", | |
"常德": "1503", | |
"长沙": "1502", | |
"长治": "2603", | |
"常州": "1604", | |
"巢湖": "106", | |
"潮州": "604", | |
"承德": "1006", | |
"郴州": "1504", | |
"赤壁": "41501", | |
"赤峰": "2105", | |
"滁州": "107", | |
"大理": "3306", | |
"大连": "1906", | |
"丹东": "1907", | |
"大庆": "1104", | |
"大同": "2604", | |
"达州": "2804", | |
"德令哈": "42572", | |
"德清": "3432", | |
"德阳": "41910", | |
"德州": "2405", | |
"定远": "40899", | |
"东海县": "40728", | |
"东胜": "40334", | |
"东营": "2406", | |
"都江堰": "41886", | |
"敦煌": "505", | |
"额济纳": "40394", | |
"峨眉": "2807", | |
"恩施": "1403", | |
"鄂州": "1404", | |
"佛山": "607", | |
"福安": "41025", | |
"福鼎": "41026", | |
"涪陵": "303", | |
"福清": "40954", | |
"抚顺": "1908", | |
"阜新": "1909", | |
"阜阳": "108", | |
"福州": "402", | |
"抚州": "1703", | |
"赣州": "1704", | |
"高密": "41181", | |
"格尔木": "42571", | |
"广安": "2809", | |
"广元": "2810", | |
"桂林": "705", | |
"贵阳": "802", | |
"海城": "40424", | |
"海口": "902", | |
"海拉尔": "40342", | |
"海宁": "40796", | |
"哈密": "3109", | |
"邯郸": "1008", | |
"杭州": "3402", | |
"涵江": "40963", | |
"汉中": "2705", | |
"鹤壁": "1204", | |
"合川": "339", | |
"合肥": "102", | |
"鹤岗": "1106", | |
"黑河": "1107", | |
"衡山": "41542", | |
"衡水": "1009", | |
"衡阳": "1505", | |
"菏泽": "2407", | |
"淮安": "1606", | |
"淮北": "110", | |
"怀化": "1506", | |
"淮南": "112", | |
"黄山": "113", | |
"黄石": "1406", | |
"呼和浩特": "2102", | |
"惠州": "609", | |
"葫芦岛": "1910", | |
"湖州": "3409", | |
"酒泉": "508", | |
"佳木斯": "1108", | |
"吉安": "1705", | |
"江门": "610", | |
"江山": "3420", | |
"胶州": "41139", | |
"嘉善": "3434", | |
"嘉兴": "3410", | |
"嘉峪关": "516", | |
"揭阳": "611", | |
"吉林": "1800", | |
"晋城": "2606", | |
"景德镇": "1706", | |
"荆门": "1419", | |
"荆州": "1408", | |
"金华": "3411", | |
"济宁": "2408", | |
"集宁": "40362", | |
"晋江": "40989", | |
"锦州": "1911", | |
"吉首": "1517", | |
"九江": "1708", | |
"鸡西": "1109", | |
"开封": "1208", | |
"凯里": "42111", | |
"喀什": "3111", | |
"库尔勒": "42628", | |
"昆明": "3302", | |
"昆山": "1631", | |
"廊坊": "1010", | |
"兰州": "502", | |
"耒阳": "1518", | |
"拉萨": "3202", | |
"梁平": "323", | |
"连江": "40949", | |
"连云港": "1610", | |
"聊城": "2410", | |
"辽阳": "1912", | |
"辽源": "1806", | |
"丽江": "3312", | |
"临汾": "2608", | |
"陵水": "904", | |
"临海": "3413", | |
"临河": "40355", | |
"临沂": "2411", | |
"六安": "115", | |
"六盘水": "807", | |
"柳州": "709", | |
"溧阳": "1630", | |
"龙岩": "404", | |
"龙游": "40817", | |
"娄底": "1508", | |
"漯河": "1209", | |
"罗源": "40950", | |
"庐山": "1709", | |
"吕梁": "2607", | |
"马鞍山": "116", | |
"满洲里": "40350", | |
"美兰": "41864", | |
"梅州": "614", | |
"绵阳": "2816", | |
"汨罗": "41565", | |
"漠河": "40679", | |
"牡丹江": "1110", | |
"南昌": "1702", | |
"南城": "41101", | |
"南充": "2818", | |
"南丰": "41103", | |
"南宁": "702", | |
"南通": "1611", | |
"南阳": "1211", | |
"内江": "2819", | |
"宁波": "3415", | |
"宁德": "406", | |
"宁海": "3437", | |
"盘锦": "1913", | |
"攀枝花": "2820", | |
"平顶山": "1212", | |
"萍乡": "1710", | |
"平遥": "2614", | |
"莆田": "407", | |
"迁安": "40040", | |
"黔江": "315", | |
"潜江": "1409", | |
"蕲春": "41492", | |
"清远": "615", | |
"青州市": "41178", | |
"秦皇岛": "1012", | |
"琼海": "905", | |
"齐齐哈尔": "1111", | |
"七台河": "1112", | |
"泉州": "408", | |
"曲阜": "2423", | |
"曲靖": "3315", | |
"渠县": "41985", | |
"衢州": "3419", | |
"任丘": "40152", | |
"日照": "2415", | |
"如皋": "1643", | |
"瑞安": "40791", | |
"乳山": "41203", | |
"三门峡": "1214", | |
"三门县": "40826", | |
"三明": "409", | |
"三亚": "906", | |
"商丘": "1215", | |
"上饶": "1711", | |
"上虞": "40803", | |
"山海关": "40042", | |
"汕头": "616", | |
"韶关": "618", | |
"绍兴": "3422", | |
"邵阳": "1509", | |
"神木": "42419", | |
"石家庄": "1002", | |
"十堰": "1410", | |
"双鸭山": "1113", | |
"四平": "1809", | |
"松江": "2517", | |
"松原": "1810", | |
"松滋": "41485", | |
"绥德": "42424", | |
"绥芬河": "40658", | |
"遂宁": "2821", | |
"随州": "1411", | |
"苏州": "1615", | |
"宿州": "117", | |
"泰安": "2416", | |
"台安": "40422", | |
"泰宁": "40976", | |
"太原": "2602", | |
"台州": "3424", | |
"泰州": "1617", | |
"唐山": "1013", | |
"滕州": "41155", | |
"天门": "1407", | |
"天水": "511", | |
"铁岭": "1914", | |
"桐城": "40888", | |
"通化": "1811", | |
"通辽": "2110", | |
"铜陵": "118", | |
"铜仁": "808", | |
"桐乡": "3431", | |
"吐鲁番": "3118", | |
"瓦房店": "40415", | |
"万宁": "908", | |
"万源": "41986", | |
"万州": "302", | |
"潍坊": "2417", | |
"威海": "2418", | |
"渭南": "2706", | |
"文昌": "909", | |
"温岭": "40829", | |
"温州": "3426", | |
"乌海": "2111", | |
"芜湖": "120", | |
"乌兰浩特": "40373", | |
"武隆": "327", | |
"武清": "3012", | |
"武威": "513", | |
"无锡": "1619", | |
"武夷山": "413", | |
"襄阳": "1416", | |
"咸宁": "1414", | |
"孝感": "1417", | |
"霞浦": "41019", | |
"西昌": "2828", | |
"锡林浩特": "40380", | |
"邢台": "1015", | |
"西宁": "2302", | |
"新乡": "1216", | |
"信阳": "1217", | |
"新余": "1712", | |
"忻州": "2610", | |
"许昌": "1218", | |
"乐清": "40792", | |
"延安": "2711", | |
"盐城": "1621", | |
"阳泉": "2611", | |
"扬州": "1622", | |
"延吉": "40547", | |
"烟台": "2419", | |
"宜宾": "2825", | |
"宜昌": "1418", | |
"宜春": "1713", | |
"银川": "2202", | |
"英德": "41737", | |
"营口": "1915", | |
"营山": "41954", | |
"鹰潭": "1714", | |
"义乌": "40810", | |
"宜兴": "1628", | |
"益阳": "1511", | |
"永嘉": "40786", | |
"永州": "1513", | |
"尤溪": "40973", | |
"岳阳": "1512", | |
"余杭": "40772", | |
"榆林": "2712", | |
"运城": "2613", | |
"余姚": "40780", | |
"枣阳": "41462", | |
"枣庄": "2420", | |
"张家界": "1514", | |
"张家口": "1016", | |
"章丘": "41131", | |
"张掖": "515", | |
"漳州": "415", | |
"湛江": "625", | |
"昭通": "3321", | |
"镇江": "1626", | |
"镇远": "42115", | |
"织金": "42106", | |
"中山": "627", | |
"中卫": "2206", | |
"钟祥": "41471", | |
"周口": "1219", | |
"珠海": "628", | |
"诸暨": "3428", | |
"驻马店": "1220", | |
"淄博": "2421", | |
"遵义": "811", | |
} | |
if __name__ == "__main__": | |
import argparse | |
parser = argparse.ArgumentParser() | |
parser.add_argument("start", choices=station_code.keys(), help="from city") | |
parser.add_argument("end", choices=station_code.keys(), help="to city") | |
parser.add_argument( | |
"-d", "--date", default=datetime.now().strftime("%Y-%m-%d"), help="travel date" | |
) | |
parser.add_argument("-o", "--offset", default=0, type=int) | |
parser.add_argument("-l", "--limit", default=10, type=int) | |
args = parser.parse_args() | |
data = get_data(args) | |
data_list = data["data"]["list"] | |
max_prices_count = max(len(x["prices"]) for x in data_list) | |
for r in data_list: | |
prices = r.pop("prices") | |
for i in range(max_prices_count): | |
r["price_{}".format(i)] = prices[i] if i < len(prices) else "" | |
print(json.dumps(data_list, ensure_ascii=False)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment