12306抢票

Posted z2529827226

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了12306抢票相关的知识,希望对你有一定的参考价值。

import requests
import re
import time
import base64
import json
import sys
import re
from urllib3 import disable_warnings
from urllib3.exceptions import InsecureRequestWarning
import base64
from urllib.parse import unquote
from datetime import datetime

#票的种类字典
PASSENGER_TICKER_STR = { 一等座: M, 特等座: P, 二等座: O, 商务座: 9, 硬座: 1, 无座: 1, 软座: 2, 软卧: 4, 硬卧: 3, }

#验证码字典
dict = {1:38,42,
        2: 110,42,
        3: 199,41,
        4: 250,48,
        5: 30,112,
        6:101,109,
        7: 187,114,
        8: 273,113}
#获取设备id
def get_id():
    head = {Host: kyfw.12306.cn,
            Referer: https://kyfw.12306.cn/otn/resources/login.html,
            User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    timestamp = int(time.time() * 1000)
    url_begin = https://kyfw.12306.cn/otn/HttpZF/logdevice?algID=wpzbylY5Yo&hashCode=KWBZ0kbbqBYDDMeReBW-uqgVhLqR-jsVxyH8lgVBdjI&FMQw=0&q4f3=zh-CN&VySQ=FGG8uUw2gGHwDDe4hE6JfQCEHprnI3cI&VPIf=1&custID=133&VEek=unspecified&dzuS=0&yD16=0&EOQP=2cfecb7a9fb59a54e281244f03c06373&jp76=d41d8cd98f00b204e9800998ecf8427e&hAqN=Linux%20x86_64&platform=WEB&ks0Q=d41d8cd98f00b204e9800998ecf8427e&TeRS=965x1699&tOHY=24xx990x1760&Fvje=i1l1s1&q5aJ=-8&wNLf=99115dfb07133750ba677d055874de87&0aew=Mozilla/5.0%20(X11;%20Ubuntu;%20Linux%20x86_64;%20rv:74.0)%20Gecko/20100101%20Firefox/74.0&E3gR=c1a681574b963932504ec5bbc2b32521&timestamp={}.format(timestamp)
    response = requests.get(url_begin,headers=head)
    return response.text
#票的列表
def check_piao():
    print("|",format("车次", "^7"),"|",format("起始站", "^7"),"|",format("终点站", "^7"),"|",format("出发时间", "^7"),"|",format("到达时间", "^7"),"|",format("历时", "^7"),"|",format("商务座", "^7"),"|",format("一等座", "^7"),"|",format("二等座", "^7"),"|")

#城市的三字码
citys = {}  # 定义一个字典
def get_station():
    response = requests.get(https://www.12306.cn/index/script/core/common/station_name_v10074.js)
    res = re.findall(var station_names =‘(.*?)‘, response.text)[0]
    data = res.split(|)
    for it in range(len(data) // 5):
        citys[data[1 + 5 * it]] = data[2 + 5 * it]

#获取info
def get_info():
    list_info = []
    response = requests.get(https://kyfw.12306.cn/otn/resources/merged/passengerInfo_js.js?scriptVersion=1.9176)
    cancel_flag = re.findall(cancel_flag:"(.*?)", response.text)[0]
    list_info.append(cancel_flag)
    bed_level_order_num = re.findall(bed_level_order_num:"(.*?)", response.text)[0]
    list_info.append(bed_level_order_num)
    return list_info

#月份字典
dic =  {01:Jan,
        02:Feb,
        03:Mar,
        04:Apr,
        05:May,
        06:Jun,
        07:Jul,
        08:Aug,
        09:Sep,
        10:Oct,
        11:Nov,
        12:Dec}

#星期
weekDic =  {1:Mon,
            2:Tue,
            3:Wed,
            4:Thu,
            5:Fri,
            6:Sat,
            7:Sun}


if __name__ == __main__:
    #获取城市的三字码
    get_station()
    #设置指纹id
    id = get_id()
    exp = re.findall("exp":"(.*?)",,id)[0]
    dfp = re.findall("dfp":"(.*?)",id)[0]
    session = requests.session()  #创建seesion对话,保持cookie,维持对话
    disable_warnings(InsecureRequestWarning)
    session.verify = False
    session.cookies.set(RAIL_EXPIRATION,exp)
    session.cookies.set(RAIL_DEVICEID, dfp)

    #生成图片
    head = {
        Host: kyfw.12306.cn,
        Origin: https://exservice.12306.cn,
        Referer: https://exservice.12306.cn/excater/index.html,
        User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    data = {"login_site":"E",
            "module":"login",
            "rand":"sjrand"}
    response = session.get(https://kyfw.12306.cn/passport/captcha/captcha-image, params=data, headers=head)
    with open(code.png,wb) as file:
        file.write(response.content)
    #check验证码
    head = {
        Host: kyfw.12306.cn,
        Origin: https://exservice.12306.cn,
        Referer: https://exservice.12306.cn/excater/index.html,
        User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    comfirm = ‘‘  # 验证码
    str = input(请输入验证码编号:)
    list_3 = str.split(,)
    for it in list_3:
        if it != list_3[0]:
            comfirm = comfirm + , + dict[it]
        else:
            comfirm = comfirm + dict[it]
    data = {"login_site": "E",
            "answer": comfirm,
            "rand": "sjrand"}
    response = session.get(https://kyfw.12306.cn/passport/captcha/captcha-check, params=data, headers=head)
    response = response.json()
    #login
    if response["result_message"] == "验证码校验成功":
        print(response["result_message"])
        head = {
            Host: kyfw.12306.cn,
            Origin: https://kyfw.12306.cn,
            Referer: https://kyfw.12306.cn/otn/resources/login.html,
            User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
        username = input(请输入账号:)
        password = input(请输入密码:)
        postData = {
                username: username,
                password: password,
                appid: otn,
                answer: comfirm}
        response = session.post(https://kyfw.12306.cn/passport/web/login,data=postData,headers=head)
        response = response.json()
        #uamtk = response["uamtk"]
        print(response[result_message])
    else:
        print(response["result_message"])
        sys.exit(0)
    #登录验证
    head = {Host: kyfw.12306.cn,
            Referer: https://kyfw.12306.cn/otn/resources/login.html,
            User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    response = session.get(https://kyfw.12306.cn/otn/login/userLogin,headers=head)
    #重定向验证
    head = {Host: kyfw.12306.cn,
            Referer: https://kyfw.12306.cn/otn/resources/login.html,
            User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    response = session.get(https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin, headers=head)
    # 获取tk
    head = {
        Host: kyfw.12306.cn,
        Origin: https://kyfw.12306.cn,
        Referer: https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin,
        User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    data = {appid: otn}
    response = session.post(https://kyfw.12306.cn/passport/web/auth/uamtk, data=data, headers=head)
    # print(response.text)
    response = response.json()
    print(第一次+response[result_message])
    tk = response["newapptk"]
    # post_tk,准备登录
    head = {
        Host: kyfw.12306.cn,
        Origin: https://kyfw.12306.cn,
        Referer: https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin,
        User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    data = {tk: tk}
    response = session.post(https://kyfw.12306.cn/otn/uamauthclient, data=data, headers=head)
    response = response.json()
    print(第二次+response[result_message]+,+response[username]+,+您好!)
    #登录1
    response = session.get(https://kyfw.12306.cn/otn/index/initMy12306Api)
    response.encoding = utf-8
    response = response.json()
    print(response[data][user_name]+response[data][user_regard])
    #登录2
    response = session.get(https://kyfw.12306.cn/otn/leftTicket/init)
    response.encoding = utf-8
    #查票
    ###########################################
    you_from = input(出发地:)
    you_from = citys[you_from]
    you_to = input(目的地:)
    you_to = citys[you_to]
    date = input(请输入日期(xxxx-xx-xx):)
    # you_from = ‘邵阳‘
    # you_from = citys[you_from]
    # you_to = ‘长沙‘
    # you_to = citys[you_to]
    # date = ‘2020-03-27‘
    ############################################
    week = datetime.strptime(date, "%Y-%m-%d").weekday()
    week = weekDic[week]
    year = date.split(-)[0]
    month = date.split(-)[1]
    month = dic[month]
    day = date.split(-)[2]
    ###########################################
    head = {Host: kyfw.12306.cn,
            Referer: https://kyfw.12306.cn/otn/leftTicket/init,
            User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    postData = {"leftTicketDTO.train_date":date,
                "leftTicketDTO.from_station":you_from,
                "leftTicketDTO.to_station":you_to,
                "purpose_codes":"ADULT"}
    response = session.get(https://kyfw.12306.cn/otn/leftTicket/query,params=postData,headers=head)
    response.encoding = utf-8
    response = response.json()
    list_1 = response[data][result]
    #以列表的形式显示票的状态,日后再写
    check_piao() #显示列表
    list_secretStr = {} #定义一个secretStr字典以便去选择
    list_station = {} #保存车次与起始站与终点站
    list_train_no = {} #记录train_no
    list_StationTelecode = {} #记录起点与终点的code
    list_train_location = {}
    邵阳北
    邵阳  
    num = 1
    for it in list_1:
        list_2 = it.split(|)
        if list_2[1] == 预订:
            from_place= list(citys.keys())[list(citys.values()).index(list_2[6])]
            to_place = list(citys.keys())[list(citys.values()).index(list_2[7])]
            print("|", format(list_2[3], "^8"), "|", format(from_place, "^8"), "|", format(to_place, "^8"), "|",format(list_2[8], "^8"), "|", format(list_2[9], "^8"), "|", format(list_2[10], "^8"), "|", format(list_2[32], "^8"),"|", format(list_2[31], "^8"), "|", format(list_2[30], "^8"), "|")
        list_secretStr[list_2[3]] = list_2[0]
        list_StationTelecode[list_2[3]] = [list_2[6],list_2[7]]
        list_train_no[list_2[3]] = list_2[2] #train_no
        list_train_location[list_2[3]] = list_2[15]
        list_station[list_2[3]] = [list(citys.keys())[list(citys.values()).index(list_2[6])],list(citys.keys())[list(citys.values()).index(list_2[7])]]
        num = 1
    while True:
        che = input(请选择您要乘坐的列车:)
        piao = input(请选择您要什么类型的票:)
        secretStr = unquote(list_secretStr[che])
        from_place = list_station[che][0]
        to_place = list_station[che][1]
        #订票1
        head = {Host: kyfw.12306.cn,
                Referer: https://kyfw.12306.cn/otn/leftTicket/init,
                User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
        postData = {_json_att:""}
        response = session.post(https://kyfw.12306.cn/otn/login/checkUser,data=postData,headers=head)
        # 订票2
        head = {Host: kyfw.12306.cn,
                Referer: https://kyfw.12306.cn/otn/leftTicket/init,
                User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
        postData = {"secretStr":secretStr,
                    "train_date":date,
                    "back_train_date":date,
                    "tour_flag":"dc",
                    "purpose_codes":"ADULT",
                    "query_from_station_name":from_place,
                    "query_to_station_name":to_place,
                    "undefined":""}
        response = session.post(https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest,data=postData,headers=head)
        response = response.json()
        if len(response["messages"]) == 0:
            print(信息提交成功!)
            break
        else:
            print(response["messages"][0])
    #订票3
    head = {Host: kyfw.12306.cn,
            Referer: https://kyfw.12306.cn/otn/leftTicket/init,
            User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    postData = {_json_att: ""}
    response = session.post(https://kyfw.12306.cn/otn/confirmPassenger/initDc, data=postData, headers=head)
    REPEAT_SUBMIT_TOKEN = re.findall(var globalRepeatSubmitToken = ‘(.*?)‘;,response.text)[0]
    leftTicketStr = re.findall(‘leftTicketStr‘:‘(.*?)‘, response.text)[0]
    key_check_isChange = re.findall(‘key_check_isChange‘:‘(.*?)‘,response.text)[0]
    #订票4
    head = {Host: kyfw.12306.cn,
            Origin: https://kyfw.12306.cn,
            Referer: https://kyfw.12306.cn/otn/confirmPassenger/initDc,
            User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    postData = {_json_att: "",
                REPEAT_SUBMIT_TOKEN: REPEAT_SUBMIT_TOKEN}
    response = session.post(https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs, data=postData, headers=head)
    response = response.json()
    response = response[data][normal_passengers][0]
    passengerTicketStr = O,0,1,{},1,{},{},N,{}.format(response[passenger_name],response[passenger_id_no],response[mobile_no],response[allEncStr])
    oldPassengerStr = {},1,{},1_.format(response[passenger_name],response[passenger_id_no])
    #下单
    info = get_info()
    head = {Host: kyfw.12306.cn,
            Origin: https://kyfw.12306.cn,
            Referer: https://kyfw.12306.cn/otn/confirmPassenger/initDc,
            User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    postData = {"cancel_flag":info[0],
                "bed_level_order_num":info[1],
                "passengerTicketStr":passengerTicketStr,
                "oldPassengerStr":oldPassengerStr,
                "tour_flag":"dc",
                "randCode":"",
                "whatsSelect":"1",
                "sessionId":"",
                "sig":"",
                "scene":"nc_login",
                "_json_att":"",
                "REPEAT_SUBMIT_TOKEN":REPEAT_SUBMIT_TOKEN}
    response = session.post(https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo, data=postData, headers=head)
    response = response.json()
    #下单2
    head = {Host: kyfw.12306.cn,
            Origin: https://kyfw.12306.cn,
            Referer: https://kyfw.12306.cn/otn/confirmPassenger/initDc,
            User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    postData = {"train_date":"{}+{}+{}+{}+00:00:00+GMT+0800+(中国标准时间)".format(week,month,day,year),
                "train_no":list_train_no[che],
                "stationTrainCode":che,
                "seatType":PASSENGER_TICKER_STR[piao],
                "fromStationTelecode":list_StationTelecode[che][0],
                "toStationTelecode":list_StationTelecode[che][1],
                "leftTicket":leftTicketStr,
                "purpose_codes":"00",
                "train_location":list_train_location[che],
                "_json_att":"",
                REPEAT_SUBMIT_TOKEN: REPEAT_SUBMIT_TOKEN}
    response = session.post(https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount, data=postData, headers=head)
    response = response.json()
    #下单3
    head = {Host: kyfw.12306.cn,
            Origin: https://kyfw.12306.cn,
            Referer: https://kyfw.12306.cn/otn/confirmPassenger/initDc,
            User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    postData = {"passengerTicketStr":passengerTicketStr,
                "oldPassengerStr":oldPassengerStr,
                "randCode":"",
                "purpose_codes":"00",
                "key_check_isChange":key_check_isChange,
                "leftTicketStr":leftTicketStr,
                "train_location":list_train_location[che],
                "choose_seats":"",
                "seatDetailType":"000",
                "whatsSelect":"1",
                "roomType":"00",
                "dwAll":"N",
                "_json_att":"",
                "REPEAT_SUBMIT_TOKEN":REPEAT_SUBMIT_TOKEN}
    response = session.post(https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue, data=postData, headers=head)
    response = response.json()
    # 下单4
    random_1 = int(time.time()*1000)
    head = {Host: kyfw.12306.cn,
            Origin: https://kyfw.12306.cn,
            Referer: https://kyfw.12306.cn/otn/confirmPassenger/initDc,
            User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    postData = {"random":random_1,
                "tourFlag":"dc",
                "_json_att":"",
                "REPEAT_SUBMIT_TOKEN":REPEAT_SUBMIT_TOKEN}
    response = session.get(https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime, params=postData,headers=head)
    response = response.json()
    #下单5
    random_2 = int(time.time() * 1000)
    head = {Host: kyfw.12306.cn,
            Origin: https://kyfw.12306.cn,
            Referer: https://kyfw.12306.cn/otn/confirmPassenger/initDc,
            User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    postData = {"random": random_2,
                "tourFlag": "dc",
                "_json_att": "",
                "REPEAT_SUBMIT_TOKEN": REPEAT_SUBMIT_TOKEN}
    response = session.get(https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime,params=postData,headers=head)
    response = response.json()
    orderSequence_no = response[data][orderId]
    #下单6
    head = {Host: kyfw.12306.cn,
            Origin: https://kyfw.12306.cn,
            Referer: https://kyfw.12306.cn/otn/confirmPassenger/initDc,
            User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0}
    postData = {"orderSequence_no":orderSequence_no,
                "_json_att":"",
                "REPEAT_SUBMIT_TOKEN":REPEAT_SUBMIT_TOKEN}
    response = session.post(https://kyfw.12306.cn/otn/confirmPassenger/resultOrderForDcQueue, data=postData,headers=head)
    response = response.json()
    print(订票成功,车次为{},请在30分钟内前往我的订单支付!.format(che))
    session.close()

 

以上是关于12306抢票的主要内容,如果未能解决你的问题,请参考以下文章

用Python3写个12306抢票脚本

Python操作12306抢票脚本

python学习教程,12306火车票抢票系统

12306 分流抢票 纯净绿色版

如何用python写一个简单的12306抢票软件

python3.7之12306抢票脚本实现