python自动12306抢票软件实现代码


Posted in Python onFebruary 24, 2018

昨天我发的是抓取的12306数据包,然后分析了一下,今天按照昨天的分析 用代码实现了,如果有需要的同学们可以看一下,实现的功能有,登录,验证码识别,自动查票,有余票点击预定, 差了最后一步提交订单。同学们可以自己研究一下。

import requests
import time
import dmpt
import re
import random
from copyheaders import headers_raw_to_dict

DEFAULT_HEADERS={
'Host':'kyfw.12306.cn',
'Connection':'keep-alive',
'Upgrade-Insecure-Requests':'1',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Referer':'https://kyfw.12306.cn/otn/index/init',
'Accept-Language':'zh-CN,zh;q=0.9',
}
def get_random():
  return str(random.random()) #生产一个18位的随机数
def get_13_time(): #一个十三位的时间戳
  return str(int(time.time()*1000))
class CN12306(object):
  def __init__(self):
    self.chufa='2018-02-03'
    self.s=requests.session()
    self.s.verify = False  # 忽略https 证书验证
  def get_init(self): #请求了一个首页
    url='https://kyfw.12306.cn/otn/login/init'
    r=self.s.get(url)
    print('首页获取成功,状态码:',r)

  def get_newpasscode(self): #这个页面不知道是干啥的,但是12306 请求了,咱们为了模仿的像一点也去请求
    url='https://kyfw.12306.cn/otn/resources/js/newpasscode/captcha_js.js?_={}'.format(get_13_time())
    r=self.s.get(url)
    print('newpasscode获取成功,状态码:',r)

  def get_auth_code(self): #获取验证码
    url='https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&{}'.format(get_random())
    r=self.s.get(url)
    with open('auth_code.png', 'wb') as auth:
      auth.write(r.content)
      auth.flush()
      auth.close()
    return str(r) == '<Response [200]>'

  def analysis_auth_code(self): # 调用打码平台,返回验证码坐标
    dmt = dmpt.DamatuApi("打码平台帐号", "打码平台密码")
    analysis_auth = dmt.decode('auth_code.png', 287) # 上传打码
    analysis_auth = re.sub('\|', ',', analysis_auth)
    li = analysis_auth.split(',')
    for i in range(len(li)):
      if i % 2 == 0:
        pass
      else:
        li[i] = str(int(li[i]) - 30)
    analysis_auth = str(li)
    analysis_auth = re.sub("'", '', analysis_auth)
    analysis_auth = re.sub("\]", '', analysis_auth)
    analysis_auth = re.sub("\[", '', analysis_auth)
    analysis_auth = re.sub(" ", '', analysis_auth)
    print('验证码坐标', analysis_auth)
    self.analysis_auth= analysis_auth # 验证码坐标

  def auth_auth_code(self): #验证验证码是否正确提交方式post
    url='https://kyfw.12306.cn/passport/captcha/captcha-check'
    data={
      'answer':self.analysis_auth ,
      'login_site':'E',
      'rand':'sjrand',
    }
    r=self.s.post(url=url,data=data)
    print(r.text)
    if r.text == '''{"result_message":"验证码校验成功","result_code":"4"}''': #验证码校验成功
      return True
    else: #如果验证码校验失败
      print('验证码错误,刷新验证码,重新提交')
      if self.get_auth_code():  #获取验证码
        self.analysis_auth_code() #调用打码平台
        self.auth_auth_code() #重新校验验证码

  def login(self):
    url='https://kyfw.12306.cn/passport/web/login'
    data={
    'username' : '12306帐号',
    'password' : '12306密码',
    'appid' : 'otn',
    }
    r=self.s.post(url=url,data=data)
    self.uamtk=r.json()["uamtk"]

    print(r.text)

  def userLogin(self):
    url='https://kyfw.12306.cn/otn/login/userLogin'
    r=self.s.post(url=url)
    # print(r.text)
  def getjs(self):  #不知道是干啥的,但是也提交吧
    url='https://kyfw.12306.cn/otn/HttpZF/GetJS'
    r=self.s.get(url)
  def post_uamtk(self):
    url='https://kyfw.12306.cn/passport/web/auth/uamtk'
    data={ 'appid':'otn'}
    r=self.s.post(url=url,data=data,allow_redirects=False)
    self.newapptk=r.json()["newapptk"]
    r.encoding='utf-8'
    print(r.text)
  def post_uamauthclient(self):
    url='https://kyfw.12306.cn/otn/uamauthclient'
    data={
      'tk':self.newapptk
    }
    r=self.s.post(url=url,data=data)
    self.apptk = r.json()["apptk"]
    r.encoding='utf-8'
    print(r.text)
  def get_userLogin(self):
    url='https://kyfw.12306.cn/otn/login/userLogin'
    r=self.s.get(url)
    r.encoding='utf-8'
    # print(r.text)
  def get_leftTicket(self):
    url='https://kyfw.12306.cn/otn/leftTicket/init'
    r=self.s.get(url)
    r.encoding='utf-8'
    # print(r.text)
  def get_GetJS(self):
    url='https://kyfw.12306.cn/otn/HttpZF/GetJS'
    self.s.get(url)

  def get_qufzjql(self):
    url = 'https://kyfw.12306.cn/otn/dynamicJs/qufzjql'
    self.s.get(url)

  def get_queryZ(self):
    url='https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes={}'.format(self.chufa,'BJP','TBP','ADULT')
    r=self.s.get(url)
    r.encoding='utf-8'
    # print(r.text)
    cheliang=r.json()["data"]["result"]
    for i in cheliang:
      dandulist=str(i).split('|')
      if len(str(dandulist[0]))>=100:
        self.secretStr=dandulist[0]
        # secretStr = str(x[0])
        车次=str(dandulist[3])
        出发时间=str(dandulist[8])
        到达时间 = str(dandulist[9])
        历时=str(dandulist[10])
        软卧 = str(dandulist[23])
        硬卧=str(dandulist[28])
        print(i)
        print('可预订车次列表,','车次:',车次,'出发时间:', 出发时间,'到达时间:', 到达时间,'历时:', 历时,'软卧剩余: ',软卧,' 硬卧剩余: ',硬卧)
        if (软卧 != '' and 软卧 != '0' and 软卧 != '无' and 软卧 != '空') or (硬卧 != '' and 硬卧 != '0' and 硬卧 != '无' and 硬卧 != '空'):
          #执行下单操作
          self.post_submitOrderRequest()
          self.post_initDc()
          self.post_getPassengerDTOs()
          return False

      print('*****************************************************')
    return True


  # 点击预定下单
  def post_submitOrderRequest(self):
    url='https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest'
    data={
      'secretStr':self.secretStr,
      'train_date':self.chufa, #出发时间
      'back_train_date':self.chufa ,#返回时间
      'tour_flag':'dc',
      'purpose_codes':'ADULT',
      'query_from_station_name':'北京',
      'query_to_station_name':'天津北',
      'undefined':''
       }
    r=self.s.post(url=url,data=data)
    print(r.text)
  def post_initDc(self):
    url='https://kyfw.12306.cn/otn/confirmPassenger/initDc'
    r=self.s.post(url)
    # r.text
    self.REPEAT_SUBMIT_TOKEN=re.findall("globalRepeatSubmitToken = '(.*?)';",r.text)[0]
  def post_getPassengerDTOs(self): #获取乘客信息
    url='https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs'
    data={
      'REPEAT_SUBMIT_TOKEN':self.REPEAT_SUBMIT_TOKEN,
      '_json_att':''
    }
    r=self.s.post(url=url,data=data)
    r.encoding='utf-8'
    print(r.text)

if __name__ == '__main__':
  print(get_random())
  cn=CN12306()
  cn.get_init()
  cn.get_newpasscode()
  if cn.get_auth_code():
    #如果验证码获取成功,就调用打码平台
    print('验证码获取成功')
    print('正在调用打码平台...')
    cn.analysis_auth_code()
    if cn.auth_auth_code(): #验证验证码是否正确
      cn.login()
      cn.userLogin()
      cn.getjs()
      cn.post_uamtk()
      cn.post_uamauthclient()
      cn.get_userLogin()
      cn.get_leftTicket()
      cn.get_GetJS()
      cn.get_qufzjql()

      while cn.get_queryZ():
        time.sleep(30)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
浅谈python中的__init__、__new__和__call__方法
Jul 18 Python
python 时间信息“2018-02-04 18:23:35“ 解析成字典形式的结果代码详解
Apr 19 Python
Python FTP两个文件夹间的同步实例代码
May 25 Python
解决python打不开文件(文件不存在)的问题
Feb 18 Python
Django在pycharm下修改默认启动端口的方法
Jul 26 Python
python内存管理机制原理详解
Aug 12 Python
面向对象学习之pygame坦克大战
Sep 11 Python
用Python画小女孩放风筝的示例
Nov 23 Python
TensorFlow tf.nn.max_pool实现池化操作方式
Jan 04 Python
详解python logging日志传输
Jul 01 Python
python两个list[]相加的实现方法
Sep 23 Python
Python中super().__init__()测试以及理解
Dec 06 Python
浅谈Python中的zip()与*zip()函数详解
Feb 24 #Python
python模仿网页版微信发送消息功能
Feb 24 #Python
python2.7读取文件夹下所有文件名称及内容的方法
Feb 24 #Python
python opencv之分水岭算法示例
Feb 24 #Python
python3爬取各类天气信息
Feb 24 #Python
python opencv之SIFT算法示例
Feb 24 #Python
python3 破解 geetest(极验)的滑块验证码功能
Feb 24 #Python
You might like
PHP实现HTML生成PDF文件的方法
2014/11/07 PHP
深入了解PHP中的Array数组和foreach
2016/11/06 PHP
php读取和保存base64编码的图片内容
2017/04/22 PHP
php post换行的方法
2020/02/03 PHP
基于PHP实现生成随机水印图片
2020/12/09 PHP
document.body.scrollTop 值总为0的解决方法 比较常见的标准问题
2009/11/30 Javascript
为Extjs加加速(javascript加速)
2010/08/19 Javascript
DIV外区域Click后关闭DIV的实现代码
2011/12/21 Javascript
JavaScript高级程序设计 阅读笔记(七) ECMAScript中的语句
2012/02/27 Javascript
js中eval()函数和trim()去掉字符串左右空格应用
2013/02/02 Javascript
javascript实现信息的显示和隐藏如注册页面
2013/12/03 Javascript
JS+CSS实现Div弹出窗口同时背景变暗的方法
2015/03/04 Javascript
jquery checkbox无法用attr()二次勾选问题的解决方法
2016/07/22 Javascript
Three.js学习之文字形状及自定义形状
2016/08/01 Javascript
微信小程序组件 contact-button(客服会话按钮)详解及实例代码
2017/01/10 Javascript
微信小程序 JS动态修改样式的实现代码
2017/02/10 Javascript
在vue项目中,使用axios跨域处理
2018/03/07 Javascript
javaScript实现游戏倒计时功能
2018/11/17 Javascript
vue权限管理系统的实现代码
2019/01/17 Javascript
微信小程序实现canvas分享朋友圈海报
2020/06/21 Javascript
vscode中Vue别名路径提示的实现
2020/07/31 Javascript
Python程序语言快速上手教程
2012/07/18 Python
基于Python Shell获取hostname和fqdn释疑
2016/01/25 Python
编写Python爬虫抓取暴走漫画上gif图片的实例分享
2016/04/20 Python
Python环境下安装使用异步任务队列包Celery的基础教程
2016/05/07 Python
详解Python函数作用域的LEGB顺序
2016/05/14 Python
Python中list初始化方法示例
2016/09/18 Python
python顺序的读取文件夹下名称有序的文件方法
2018/07/11 Python
python实现事件驱动
2018/11/21 Python
Python3进制之间的转换代码实例
2019/08/24 Python
wxPython电子表格功能wx.grid实例教程
2019/11/19 Python
python实现扑克牌交互式界面发牌程序
2020/04/22 Python
测绘工程本科生求职信
2013/10/10 职场文书
人力资源本科毕业生求职信
2014/06/04 职场文书
SQLServer2019 数据库的基本使用之图形化界面操作的实现
2021/04/08 SQL Server
python3实现常见的排序算法(示例代码)
2021/07/04 Python