利用python代码写的12306订票代码


Posted in Python onDecember 20, 2015

本文实例讲述了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'<script src="(/otn/dynamicJs/.*?)" type="text/javascript" xml:space="preserve"></script>', 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程序设计有所帮助。

Python 相关文章推荐
用Python编程实现语音控制电脑
Apr 01 Python
python插入数据到列表的方法
Apr 30 Python
python算法演练_One Rule 算法(详解)
May 17 Python
python实现壁纸批量下载代码实例
Jan 25 Python
学生信息管理系统Python面向对象版
Jan 30 Python
Django uwsgi Nginx 的生产环境部署详解
Feb 02 Python
计算机二级python学习教程(1) 教大家如何学习python
May 16 Python
python爬虫 模拟登录人人网过程解析
Jul 31 Python
利用PyQt中的QThread类实现多线程
Feb 18 Python
matplotlib运行时配置(Runtime Configuration,rc)参数rcParams解析
Jan 05 Python
五分钟学会怎么用Pygame做一个简单的贪吃蛇
Jan 06 Python
上帝为你开了一扇窗之Tkinter常用函数详解
Jun 02 Python
python从入门到精通(DAY 1)
Dec 20 #Python
在DigitalOcean的服务器上部署flaskblog应用
Dec 19 #Python
用ReactJS和Python的Flask框架编写留言板的代码示例
Dec 19 #Python
使用Python编写简单的端口扫描器的实例分享
Dec 18 #Python
十个Python程序员易犯的错误
Dec 15 #Python
Python学习笔记整理3之输入输出、python eval函数
Dec 14 #Python
Python中内置数据类型list,tuple,dict,set的区别和用法
Dec 14 #Python
You might like
关于php fread()使用技巧
2010/01/22 PHP
PHP mcrypt可逆加密算法分析
2011/07/19 PHP
PHP面向对象法则
2012/02/23 PHP
去掉destoon资讯内容页keywords关键字自带的文章标题的方法
2014/08/21 PHP
php分页函数完整实例代码
2014/09/22 PHP
laravel ORM关联关系中的 with和whereHas用法
2019/10/16 PHP
用jquery方法操作radio使其默认选项是否
2013/09/10 Javascript
javasciprt下jquery函数$.post执行无响应的解决方法
2014/03/13 Javascript
jQuery EasyUI学习教程之datagrid点击列表头排序
2016/07/09 Javascript
jquery pagination分页插件使用详解(后台struts2)
2017/01/22 Javascript
socket.io学习教程之基本应用(二)
2017/04/29 Javascript
简单实现jQuery上传图片显示预览功能
2020/06/29 jQuery
Angularjs按需查询实例代码
2017/10/30 Javascript
vue使用better-scroll实现下拉刷新、上拉加载
2018/11/23 Javascript
vue实现的下拉框功能示例
2019/01/29 Javascript
vue踩坑记录之数组定义和赋值问题
2019/03/20 Javascript
JS运算符简单用法示例
2020/01/19 Javascript
python冒泡排序算法的实现代码
2013/11/21 Python
python基础教程之类class定义使用方法
2014/02/20 Python
python动态加载包的方法小结
2016/04/18 Python
Python中的sort()方法使用基础教程
2017/01/08 Python
对Python3 goto 语句的使用方法详解
2019/02/16 Python
Tensorflow 定义变量,函数,数值计算等名字的更新方式
2020/02/10 Python
解决Python中报错TypeError: must be str, not bytes问题
2020/04/07 Python
Pytorch转tflite方式
2020/05/25 Python
pandas分批读取大数据集教程
2020/06/06 Python
HTML5+CSS3应用详解
2014/02/24 HTML / CSS
街头时尚在线:JESSICABUURMAN
2019/06/16 全球购物
大学迎新晚会主持词
2014/03/24 职场文书
公证委托书模板
2014/04/03 职场文书
优秀高中学生评语
2014/12/30 职场文书
婚礼双方父亲致辞
2015/07/27 职场文书
大学同学聚会感言
2015/07/30 职场文书
小学运动会开幕词
2016/03/04 职场文书
python 下载文件的几种方式分享
2021/04/07 Python
索尼ICF-5900W收音机测评
2022/04/24 无线电