必威体育Betway必威体育官网
当前位置:首页 > IT技术

12306自动抢票软件

时间:2019-08-18 21:44:35来源:IT技术作者:seo实验室小编阅读:55次「手机版」
 

自动抢票软件

一、说明

12306目前反爬虫手段做的越来越牛逼了,一旦检测到,直接就封号了或者很容易导致登录失败,必须更换代理服务器才能登录,所以做测试的时候一定要小心,要先把代理IP池搞好,再做测试。

二、代理IP池

1、获取代理IP途径,获取代理IP链接,记得将ip、端口协议类型都获取下来,存放到一个文本中

2、获取的代理IP可能不存活,如果想验证IP的存活性的话,可以使用nmap进行验证,具体验证方式不做详细讲解,可以百度

三、code

实现此code目前遇到的问题难点

  • 识别12306登录验证码,这个验证码是随机出现的图片,肉眼都很难识别,更别说程序了;目前知道的有三种方式可以识别
  1. 第一种:专业打码平台,调用API就可以验证,但是这个要花钱购买
  2. 第二种:深度学习图片识别,采集大量的12306登录验证码图片,进行训练模型,将模型训练的精确度比较高的时候,可以用来识别登录图片
  3. 第三种:12306其实利用的是根据图片所在的坐标来识别输入的验证码是否准确的,图片的坐标在verify_code函数中有注释,1:(45,45)代表第一张图片的识别坐标范围:横坐标为0-45,纵坐标为0-45,只要输入在这个范围,则登录就会验证通过;本程序目前采用的就是先把登录验证的图片下载下来,根据肉眼匹配图片,输入坐标就可登录成功,如果有大神可以利用第二种方式来实现
import http.cookiejar as cookielib
from json import loads
import re
import os
import time
import random
import requests

requests.packages.urllib3.disable_warnings()


def get_random():
    return str(random.random())  # 生产一个18位的随机数


def get_13_time():  # 一个十三位的时间戳
    return str(int(time.time() * 1000))


def load_file(file_name):
    datas = []
    if file_name is not None and os.path.isfile(file_name):
        with open(file_name, 'r') as f:
            for line in f:
                line = line.encode('utf-8').decode('utf-8-sig').strip().lower()
                if line:
                    datas.APPend(line)
    return datas


class CN12306:
    def __init__(self):
        # 代理IP获取网站
        self.start_time = '2018-07-15'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36'
        }
        self.s = requests.session()
        self.ips = load_file('ips.lt')
        self.proxies = {'http': random.choice(self.ips)}
        self.s.cookies = cookielib.LWPCookieJar(filename='cookie')

    def get_init(self):  # 请求了一个首页
        url = 'https://kyfw.12306.cn/otn/login/init'
        r = self.s.get(url, proxies=self.proxies, headers=self.headers, verify=False)
        print('首页获取成功,状态码:', r)

    def get_image_code(self):
        url = "https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&{}".format(
            random.random())
        response = self.s.get(url=url, proxies=self.proxies, headers=self.headers, verify=False)
        with open(r'H:\pictures\12306自动抢票\code.png', 'wb') as f:
            f.write(response.content)

    def generate_code_list(self, code_str):
        code_str = code_str.strip()
        groups = code_str.split(',')
        codes = []
        check_list = ['35,35', '105,35', '175,35', '245,35', '35,105', '105,105', '175,105', '245,105']
        for group in groups:
            codes.append(check_list[int(group) - 1])

        return ','.join(codes)

    def verify_code(self):
        # {1:(45,45)}{2:(120,45)}{3:(180,45)}{4:(255,45)}{5:(45,120)}{6:(120,120)}{7:(180,120)}{8:(255,120)}
        self.get_image_code()
        code = input('输入验证码:')
        code = self.generate_code_list(code)
        data = {
            'answer': code,
            'login_site': 'E',
            'rand': 'sjrand'
        }
        url = 'https://kyfw.12306.cn/passport/captcha/captcha-check'
        resp = self.s.post(url, data=data, proxies=self.proxies, headers=self.headers, verify=False)
        result = loads(resp.text)
        if result['result_code'] == '4':
            return True
        else:
            return false

    def login(self):
        url = 'https://kyfw.12306.cn/passport/web/login'
        data = {
            'username': '',   # 个人12306用户名
            'password': '',   # 个人12306用户密码
            'appid': 'otn',
        }
        resp = self.s.post(url=url, proxies=self.proxies, data=data, headers=self.headers, verify=False)
        result = loads(resp.text)
        print(result)
        if result['result_code'] == 0:
            self.uamtk = result['uamtk']
            return True
        else:
            return False

    def userLogin(self):
        url = 'https://kyfw.12306.cn/otn/login/userLogin'
        r = self.s.post(url=url, proxies=self.proxies, headers=self.headers, verify=False)
        # print(r.text)

    def getjs(self):
        url = 'https://kyfw.12306.cn/otn/HttpZF/GetJS'
        r = self.s.get(url, proxies=self.proxies, headers=self.headers, verify=False)

    def post_uamtk(self):
        url = 'https://kyfw.12306.cn/passport/web/auth/uamtk'
        data = {'appid': 'otn'}
        r = self.s.post(url=url, data=data, proxies=self.proxies, allow_redirects=False, headers=self.headers, verify=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, proxies=self.proxies, headers=self.headers, verify=False)
        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, proxies=self.proxies, headers=self.headers, verify=False)
        r.encoding = 'utf-8'
        # print(r.text)

    def get_leftticket(self):
        url = 'https://kyfw.12306.cn/otn/leftTicket/init'
        r = self.s.get(url, proxies=self.proxies, headers=self.headers, verify=False)
        r.encoding = 'utf-8'
        # print(r.text)

    def get_GetJS(self):
        url = 'https://kyfw.12306.cn/otn/HttpZF/GetJS'
        self.s.get(url, proxies=self.proxies, headers=self.headers, verify=False)

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

    def get_queryZ(self):
        url = 'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes={}'.format(
            self.start_time, 'XAY', 'WNY', 'ADULT')
        r = self.s.get(url, headers=self.headers, proxies=self.proxies, verify=False)
        r.encoding = 'utf-8'
        print(loads(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])
                硬座 = str(dandulist[29])
                无座 = str(dandulist[26])

                if "G" in 车次 or "D" in 车次:
                    print(i)
                    print('可预订车次列表,', '车次:', 车次, '出发时间:', 出发时间, '到达时间:',
                          到达时间, '历时:', 历时, '软卧: ', 软卧, ' 硬卧: ', 硬卧, ' 硬座: ', 硬座, ' 无座: ', 无座)

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

    # 点击预定下单
    def post_submitorderRequest(self):
        url = 'https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest'
        data = {
            'secretStr': self.secretStr,
            'train_date': self.start_time,       # 出发时间
            'back_train_date': self.start_time,  # 返回时间
            'tour_flag': 'dc',
            'purpose_codes': 'ADULT',
            'query_from_station_name': '西安',
            'query_to_station_name': '渭南',
            'undefined': ''
        }
        r = self.s.post(url=url, proxies=self.proxies, data=data, headers=self.headers, verify=False)
        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, proxies=self.proxies, data=data, headers=self.headers, verify=False)
        r.encoding = 'utf-8'
        print(r.text)


if __name__ == '__main__':
    # main_()
    cn = CN12306()
    if cn.verify_code():
        print("验证码校验成功")
    else:
        print("验证码校验失败")
        exit(1)

    if cn.login():
        print("账户登录成功")
    else:
        print("账户登录失败")
        exit(1)

    # cn.userLogin()
    cn.getjs()
    cn.post_uamtk()
    cn.post_uamauthclient()
    # cn.get_userLogin()
    cn.get_leftTicket()
    cn.get_GetJS()
    cn.get_qufzjql()
    cn.get_queryZ()

    # while cn.get_queryZ():
    #     time.sleep(60)

分享即快乐

以上代码仅仅业余爱好实现,切勿对12306平台造成任何破坏 

如有技术问题,欢迎指正

相关阅读

利用手机12306自动刷火车票的教程

春运时期一票难求,为买到心仪的火车票我们需要使用手机、电脑来进行抢票。手机12306客户端为此也提供了自动刷票的功能,那么该如何

【解决方案】chrome打开新标签页自动打开chrome://new

简述 天,昨天开始遇到这个问题,还没有留心,结果今天多次使用chrome的时候,就发现有些不对了。。打开chrome的新标签页,结果出现了自动

淘宝卖家怎么设置问答?自动回复如何设置?

我们在淘宝商城购物的时候,一般都会去咨询客服一些问题,比如说尺寸适合哪个尺、发什么快递、质量怎么样等等,这些问题都是很常见的,10

开机自动拨号

方法一 最简单的开机启动 https://zhinan.sogou.com/guide/detail/?id=1610009617 方法二 https://jingyan.baidu.com/article/20

自动装配的几种方式——Spring IOC/DI(四)

本章主要讲解自动装配的几种方式,接上一章依赖注入的方式以及装配属性:https://blog.csdn.net/qq_34598667/article/details/83308

分享到:

栏目导航

推荐阅读

热门阅读