本文实例讲述了python代码写的12306订票代码,分享给大家供大家参考。
具体实现方法如下:
import datetime
import json
import re
import sys
import time
import Image
import PyV8
import requests
import tools.email_helper as emailHelper
reload(sys)
sys.setdefaultencoding(\'utf-8\') # @UndefinedVariable
reqSingle = requests.Session()
attCheCi=[\"G655\",\"G6741\",\"G67\",\"G491\"] #关注的车次
dateList=[\"2015-02-18\"] #关注的日期
username=\"12306登录用户名\"
password=\"登录密码\"
#这个是需要手动提交订单后f12自己找的,挨个post请求去找,参数名为:oldPassengerStr 格式如下
oldPassengerStr=\"姓名,1,130434199802036011,1_姓名2,1,130434199204238069,1_\"
#这个是需要手动提交订单后f12自己找的,挨个post请求去找,参数名为:passengerTicketStr 格式如下
passengerTicketStr=\"O,0,1,姓名,1,130434199802036011,13683456789,N_O,0,1,姓名2,1,130434199204238069,13683456789,N\"
header={
\"Accept\":\"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",
\"Accept-Encoding\":\"gzip, deflate\",
\"Accept-Language\":\"zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\",
\"Connection\":\"keep-alive\",
\"Host\":\"kyfw.12306.cn\",
\"Referer\":\"https://kyfw.12306.cn/otn/safeguard/init\",
\"User-Agent\":\"Mozilla/5.0 (Windows NT 5.1; rv:34.0) Gecko/20100101 Firefox/34.0\"
}
##定火车票
def orderTicket(fromStation,toStation,trainDate,secretStr):
header[\"Referer\"]=\"https://kyfw.12306.cn/otn/leftTicket/init\"
orderInitReq= reqSingle.get(\"https://kyfw.12306.cn/otn/leftTicket/init\",headers=header)
header[\"Referer\"]=\"https://kyfw.12306.cn/otn/leftTicket/init\"
aryKV=extractKey(orderInitReq.content,header)
print aryKV
#初始化订票
header[\"Referer\"]=\"https://kyfw.12306.cn/otn/leftTicket/init\"
orderInitReq= reqSingle.post(\"https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest\",data={
aryKV[0]:aryKV[1],
\"train_date\":trainDate,
\"myversion\":\"undefined\",
\"purpose_codes\":\"ADULT\",
\"query_from_station_name\":fromStation,
\"query_to_station_name\":toStation,
\"secretStr\":secretStr,
\"tour_flag\":\"dc\",
\"back_train_date\":time.strftime(\'%Y-%m-%d\',time.localtime(time.time())),
\"undefined\":\"\"
},headers=header)
print orderInitReq.content
orderInitJson=orderInitReq.json()
if orderInitJson.get(\"status\")==False or orderInitJson.get(\"httpstatus\")!=200:
raise Exception(\"订票出现错误\")
initDcReq= reqSingle.post(\"https://kyfw.12306.cn/otn/confirmPassenger/initDc\", data={\"_json_att\":\"\"},headers=header)
header[\"Referer\"]=\"https://kyfw.12306.cn/otn/confirmPassenger/initDc\"
aryKV=extractKey(initDcReq.content,header)
match =re.search(\"var globalRepeatSubmitToken = \'(.*?)\';\", initDcReq.content)
ticketToken=match.group(1)
lianxirenReq=reqSingle.post(\"https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs\", data={\"REPEAT_SUBMIT_TOKEN\":ticketToken,\"_json_att\":\"\"},headers=header)
lianxirenJson=lianxirenReq.json()
#验证码
#开始做验证码
while True:
r=reqSingle.get(\"https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=passenger&rand=randp&\",verify=False,timeout=5,headers=header)
with open(\"orderRand.jpg\",\"wb\") as rimg:
rimg.write(r.content)
pass
img=Image.open(\"orderRand.jpg\")
img.show()
randCode=raw_input(\"请输入登录验证码:\")
#验证验证码
randReq= reqSingle.post(\"https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn\",data={
\"REPEAT_SUBMIT_TOKEN\":ticketToken,
\"_json_att\":\"\",
\"rand\":\"randp\",
\"randCode\":randCode},headers=header)
randRes=randReq.json()
if randRes.get(\"status\") and randRes.get(\"httpstatus\")==200 and randRes.get(\"data\").get(\"result\")==\"1\":
break;
pass
print \"验证码输入正确!\"
#检查票
checkOrderInfoReq=reqSingle.post(\"https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo\", data={
aryKV[0]:aryKV[1],
\"REPEAT_SUBMIT_TOKEN\":ticketToken,
\"_json_att\":\"\",
\"bed_level_order_num\":\"000000000000000000000000000000\",
\"cancel_flag\":2,
\"oldPassengerStr\":oldPassengerStr,
\"passengerTicketStr\":passengerTicketStr,
\"randCode\":randCode,
\"tour_flag\":\"dc\"
})
checkOrderInfoJson=checkOrderInfoReq.json()
if checkOrderInfoJson.get(\"status\")==False or checkOrderInfoJson.get(\"httpstatus\")!=200:
raise Exception(\"检查票出现错误\")
pass
fromStationTelecode=re.search(\"\'from_station_telecode\':\'(.*?)\'\", initDcReq.content).group(1)
leftTicket=re.search(\"\'ypInfoDetail\':\'(.*?)\'\", initDcReq.content).group(1)
purpose_codes=re.search(\"\'purpose_codes\':\'(.*?)\'\", initDcReq.content).group(1)
station_train_code=re.search(\"\'station_train_code\':\'(.*?)\'\", initDcReq.content).group(1)
to_station_telecode=re.search(\"\'to_station_telecode\':\'(.*?)\'\", initDcReq.content).group(1)
train_no=re.search(\"\'train_no\':\'(.*?)\'\", initDcReq.content).group(1)
queueCountReq=reqSingle.post(\"https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount\",data={
\"REPEAT_SUBMIT_TOKEN\":ticketToken,
\"_json_att\":\"\",
\"fromStationTelecode\":fromStationTelecode,
\"leftTicket\":leftTicket,
\"purpose_codes\":purpose_codes,
\"seatType\":0,
\"stationTrainCode\":station_train_code,
\"toStationTelecode\":to_station_telecode,
\"train_date\":datetime.datetime.fromtimestamp(time.mktime(time.strptime(trainDate,\'%Y-%m-%d\'))).strftime(\'%a %b %d %Y %H:%M:%S GMT+0800\'),
\"train_no\":train_no
},headers=header)
queueCountJson=queueCountReq.json()
print queueCountReq.content
if queueCountJson.get(\"status\")==False or queueCountJson.get(\"httpstatus\")!=200:
raise Exception(\"获取队列错误\")
#确认队列
key_check_isChange=re.search(\"\'key_check_isChange\':\'(.*?)\'\", initDcReq.content).group(1)
train_location=re.search(\"\'train_location\':\'(.*?)\'\", initDcReq.content).group(1)
singleForQueueReq=reqSingle.post(\"https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue\",data={
\"REPEAT_SUBMIT_TOKEN\":ticketToken,
\"_json_att\":\"\",
\"dwAll\":\"N\",
\"key_check_isChange\":key_check_isChange,
\"leftTicketStr\":leftTicket,
\"oldPassengerStr\":oldPassengerStr,
\"passengerTicketStr\":passengerTicketStr,
\"purpose_codes\":purpose_codes,
\"randCode\":randCode,
\"train_location\":train_location
},headers=header)
singleForQueueJson=singleForQueueReq.json()
print singleForQueueReq.content
if singleForQueueJson.get(\"status\")==False or singleForQueueJson.get(\"httpstatus\")!=200:
raise Exception(\"confirmSingleForQueue异常\")
if singleForQueueJson.get(\"data\") is None or singleForQueueJson.get(\"data\").get(\"submitStatus\")==False:
raise Exception(\"confirmSingleForQueue异常\")
#等待orderid
while True:
orderWaitReq= reqSingle.get(\"https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime\",data={\"REPEAT_SUBMIT_TOKEN\":ticketToken,
\"_json_att\":\"\",
\"random\":time.time(),
\"tourFlag\":\"dc\"
},headers=header)
print orderWaitReq.content
orderWaitJson=orderWaitReq.json()
if orderWaitJson.get(\"status\") and orderWaitJson.get(\"httpstatus\")==200:
if orderWaitJson.get(\"data\") is not None and orderWaitJson.get(\"data\").get(\"orderId\") is not None:
orderId=orderWaitJson.get(\"data\").get(\"orderId\")
break
pass
pass
#进入队列
dcQueueReq=reqSingle.post(\"https://kyfw.12306.cn/otn/confirmPassenger/resultOrderForDcQueue\",data={
\"REPEAT_SUBMIT_TOKEN\":ticketToken,
\"_json_att\":\"\",
\"orderSequence_no\":orderId
}
,headers=header)
dcQueueJson=dcQueueReq.json()
if dcQueueJson.get(\"status\") and dcQueueJson.get(\"httpstatus\")==200 and dcQueueJson.get(\"data\") is not None and dcQueueJson.get(\"data\").get(\"submitStatus\"):
print \"订票成功\"
pass
else:
print dcQueueJson.content
print \"订票失败\"
pass
#https://kyfw.12306.cn/otn/confirmPassenger/resultOrderForDcQueue
pass
#检查是否登录
def checkIsLogin():
checkReq= reqSingle.post(\"https://kyfw.12306.cn/otn/login/checkUser\", data={\"_json_att\":\"\"},headers=header)
print u\"检查是否登录\"+checkReq.content
checkReqJson=checkReq.json()
if checkReqJson.get(\"status\") and checkReqJson.get(\"httpstatus\")==200:
if checkReqJson.get(\"data\") is not None and checkReqJson.get(\"data\").get(\"flag\"):
return True
pass
return False
pass
#提取js加密内容后的key和value
def extractKey(htmlContent,headerxx):
loginMatch=re.search(r\'\', htmlContent)
jsUrl=\"https://kyfw.12306.cn\"+ loginMatch.group(1)
jsReq=reqSingle.get(jsUrl,verify=False,timeout=15,headers=headerxx)
jsContent= jsReq.content
jsMatch=re.search(\"(function bin216.*?)function aj\", jsContent)
jsEncode= jsMatch.group(1)#获取加密的js内容
keyMatch=re.search(\"var key=\'(.*?)\'\",jsContent)
loginKey= keyMatch.group(1)#获取登录的key
ctx=PyV8.JSContext()
ctx.enter()
ctx.eval(jsEncode)
loginValue=ctx.locals.encode32(ctx.locals.bin216(ctx.locals.Base32.encrypt( \"1111\",loginKey)))
return [loginKey,loginValue]
pass
#登录操作
def login():
header[\"Referer\"]=\"https://kyfw.12306.cn/otn/login/init\"
r=reqSingle.get(\"https://kyfw.12306.cn/otn/login/init\",verify=False,timeout=15,headers=header)
loginContent=r.content
aryKV=extractKey(loginContent,header)
#开始做验证码
while True:
r=reqSingle.get(\"https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&\",verify=False,timeout=5,headers=header)
with open(\"loginRand.jpg\",\"wb\") as rimg:
rimg.write(r.content)
pass
img=Image.open(\"loginRand.jpg\")
img.show()
randCode=raw_input(\"请输入登录验证码:\")
#验证验证码
randReq= reqSingle.post(\"https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn\",data={\"rand\":\"sjrand\",\"randCode\":randCode},headers=header)
randRes=randReq.json()
if randRes.get(\"status\") and randRes.get(\"httpstatus\")==200 and randRes.get(\"data\").get(\"result\")==\"1\":
break;
pass
print \"验证码输入正确!\"
#开始登陆
loginRes=reqSingle.post(\"https://kyfw.12306.cn/otn/login/loginAysnSuggest\",data={
aryKV[0]:aryKV[1],
\"loginUserDTO.user_name\":username,
\"userDTO.password\":password,
\"randCode\":randCode,
\"myversion\":\"undefined\",
\"randCode_validate\":\"\"
},headers=header)
print repr(r.request)
print loginRes.content
loginResJson=loginRes.json()
if loginResJson.get(\"status\") and loginResJson.get(\"httpstatus\")==200:
if loginResJson.get(\"data\") is not None and loginResJson.get(\"data\").get(\"loginCheck\")==\"Y\":
print \"登录成功\"
else:
raise Exception(loginRes.content)
else:
login()
pass
def checkTicket(dtStr):
print dt
while True:
try:
r= requests.get(\"https://kyfw.12306.cn/otn/leftTicket/queryT?leftTicketDTO.train_date=\"+dtStr+\"&leftTicketDTO.from_station=BXP&leftTicketDTO.to_station=HDP&purpose_codes=ADULT\",verify=False,timeout=5,headers=header)
break
except Exception:
pass
pass
#print r.contentfd
print r.content
try:
queryDataJson= json.loads(r.content)
except Exception:
return
if queryDataJson[\"httpstatus\"]==200 and queryDataJson[\"status\"] :
#print queryDataJson[\"data\"]
for checi in queryDataJson[\"data\"]:
tmpData=checi[\"queryLeftNewDTO\"]
trainCode=tmpData.get(\"station_train_code\")
#yzNum=tmpData.get(\"yz_num\")
yzNum=tmpData.get(\"ze_num\")
if trainCode in attCheCi:
if yzNum!=\"--\" and yzNum!=\"无\" and (yzNum==\"有\" or int(yzNum)>=2):
#发邮件
fromStation=tmpData.get(\"start_station_name\")
toStation=tmpData.get(\"end_station_name\")
secretStr=checi.get(\"secretStr\")
orderTicket(fromStation, toStation, dtStr, secretStr)
# body=dtStr+\"-\"+trainCode+\"-\"+yzNum+u\"个硬座\"
# print body
# mailer=emailHelper.email_helper(\"smtp.qq.com\", \"fd\", \"fss\", \"qq.com\",\"plain\")
# mailer.send(\"630419595@qq.com\", u\"有火车票了\",body)
# raise Exception(\"有票了\")
pass
print trainCode+yzNum
pass
pass
pass
if __name__ == \'__main__\':
# login()
# if checkIsLogin():
# print \"登录成功\"
#
# orderTicket(\"北京西\",\"邯郸东\",\"2015-01-14\",\"MjAxNS0wMS0xNCMwMCNHNjczMSMwMjoxNSMwNzowNSMyNDAwMEc2NzMxMDUjQlhQI0hQUCMwOToyMCPljJfkuqzopb8j6YKv6YO45LicIzAxIzA2I08wMDAwMDA4MThNMDAwMDAwMTEwOTAwMDAwMDAyNiNQMiMxNDE5MDg2OTU2MTA0IzI5NEI0QkY0QTU2ODE2RDU1MzE5RkRCRkVEQzQ3Mzk2MUEyRUEwOEM0MUVCMjZGMDc3RUUyNzc0\")
# exit()
login()
if checkIsLogin():
print \"登录成功\"
while True:
checkCount=0
for dt in dateList:
checkTicket(dt)
time.sleep(2)
checkCount+=1
if checkCount%10==0:
if checkIsLogin():
print \"成功状态\"
else:
print \"被踢了\"
pass
pass
大家抢到回家过年的车票了吗?
希望本文所述对大家的Python程序设计有所帮助。