2015年4月18日 星期六 晴
总看到有人问Python能做啥,我突然想到一句“随心所欲不逾矩”,我觉得干啥都行啊,做web、爬虫、文本处理、各种小工具,开发的都很快的。本文举个例子。
最近hh五一要去洛阳一趟,不想坐飞机,我帮她看回来的火车票。反正我经常坐在电脑面前的,写了个程序实时监控12306有没有票。刚刚抢到了一张西安到上海的动车卧铺,也就比洛阳多100多块钱,就买下来了。单张741,跟机票钱差不多,她还是喜欢坐火车多一点,感觉火车安全。
[code] #! /usr/bin/env python #coding=utf-8 #Author = yyobin@gmail.com
import urllib,urllib2,socket import time import winsound
try: import json except: import simplejson as json
def get_url_data(url): nFail = 0 while nFail < 5: try: sock = urllib.urlopen(url) htmlSource = sock.read() sock.close() return htmlSource except Exception,e: nFail += 1 print “get url fail:%s count=%d,Exception=%s” % (url,nFail,e) time.sleep(2) print “get url fail:%s” % (url) return None
def getTicketCount(yp_info): """ 从余票字符串中获得余票数据。 余票信息字符串如下: 1018053038405095000010180500003032150000 O055300502M0933000989174800019 返回的是一个余票字典,并不是很全面,只取了我需要的类型,如下 ZY 一等座 ZE 二等座 WZ 无座 YZ 硬座 YW 硬卧 RW 软卧 """ ticketCountDesc = “”;
本次列车您选择的席别尚有余票94张
seatTicket = 0; # 所选席别余票多少张
无座179张
withoutSeatTicket = 0; # 无座票多少张
seat = {“WZ”:0, “YZ”:0, “YW”:0, “RW”:0, “ZY”:0, “ZE”:0}
i = 0; while i in range(len(yp_info)):
1012853744403485005310128513393022250000
group = yp_info[i:i+10];
1(席别)
seatType = group[:1];
硬座: 1, 硬卧: 3, 软卧: 4, 二等座:O, 一等座:M
3179
count = group[6:10]; while len(count) > 1 and count[0:1] == “0”: # count为0000的情况, count最终等于0 count = count[1:1+len(count)];
3179
count = int(count); if seatType == “1”: if count < 3000: seat[‘YZ’] = count else: seat[‘WZ’] = count - 3000 elif seatType == “3”: seat[‘YW’] = count elif seatType == “4”: seat[‘RW’] = count elif seatType == “M”: seat[‘ZY’] = count elif seatType == “O”: if count < 3000: seat[‘ZE’] = count else: seat[‘WZ’] = count - 3000 i = i + 10 return seat
def main(): socket.setdefaulttimeout(60) baseurl = ‘https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=%s&leftTicketDTO.from_station=%s&leftTicketDTO.to_station=%s&purpose_codes=ADULT' #限定出发日期 startdates = (‘2015-05-02’,‘2015-05-03’) #限定始发车站 SRC = (‘ZZF’,‘LYF’,‘XAY’,‘HSY’,‘WNY’,‘SMF’,) #指定终点 DEST = ‘SHH’
trainDict = {}
while 1:
for startdate in startdates:
for src in SRC:
try:
url = baseurl % (startdate,src,DEST)
rsp = get_url_data(url)
if rsp:
mydict = json.loads(rsp)
if mydict[‘httpstatus’] == 200:
for item in mydict[‘data’]:
if item[‘secretStr’]:
seat = getTicketCount(item[‘queryLeftNewDTO’][‘yp_info’])
if seat[‘RW’] + seat[‘YW’] + seat[‘ZE’] + seat[‘ZY’]:
traincode = item[‘queryLeftNewDTO’][‘station_train_code’]
starttime = item[‘queryLeftNewDTO’][‘start_time’]
bNotify = False
if traincode[0] == ‘D’:
if startdate == ‘2015-05-02’ and int(starttime[:2]) > 19:
bNotify = True
elif startdate == ‘2015-05-03’:
bNotify = True
if traincode[0] == ‘T’ or traincode[0] == ‘K’:
if startdate == ‘2015-05-02’ and int(starttime[:2]) > 15:
bNotify = True
if bNotify:
k = ‘%s%s%s’ % (traincode,src,startdate)
if k not in trainDict:
trainDict[k] = 1
result = ‘%s city=%s startTime=%s %s,RW=%d,YW=%d,Z1=%d,Z2=%d’ %
(traincode,src,startdate,starttime,seat[‘RW’],seat[‘YW’],seat[‘ZY’],seat[‘ZE’])
print result
winsound.Beep(3000, 5000)
winsound.PlaySound(“SystemExclamation”, winsound.SND_ALIAS)
time.sleep(1)
except Exception , e:
print e
time.sleep(60)
if name == “main”: main() [/code]
打印的结果大概是这样子的: K154 city=ZZF startTime=2015-05-02 18:21,RW=0,YW=2,Z1=0,Z2=0 K4056 city=ZZF startTime=2015-05-02 19:00,RW=31,YW=0,Z1=0,Z2=0 K284 city=ZZF startTime=2015-05-02 19:38,RW=0,YW=1,Z1=0,Z2=0 D308 city=XAY startTime=2015-05-02 21:03,RW=217,YW=0,Z1=0,Z2=0 D308 city=HSY startTime=2015-05-02 21:48,RW=25,YW=0,Z1=0,Z2=0 D308 city=WNY startTime=2015-05-02 21:26,RW=24,YW=0,Z1=0,Z2=0
电脑主机如果有喇叭的话,会beep提醒。
如果加上众多github上对12306的图形验证码识别的成果,再改一下应该就可以自动购票了。我就不折腾了,不靠这碗饭吃。
...