ruogu

研究不易

 

import requests
import re
import urllib.parse
import json
import datetime
from collections import OrderedDict
self=requests.session()
self.verify=False
self.headers={
    \'Accept\':\'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\',
    \'Accept-Encoding\':\'gzip, deflate, br\',
    \'Accept-Language\':\'zh-CN,zh;q=0.9\',
    \'Connection\':\'keep-alive\',
    \'Host\':\'kyfw.12306.cn\',
    \'Cache-Control\':\'no-cache\',
    \'User-Agent\':\'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36\',
    }
def dow():
    url=\'https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand\'
    requests.packages.urllib3.disable_warnings()
    res=self.get(url)
    print(res.status_code)
    if res.status_code==200:
       with open(\'login.jpg\',\'wb\') as f:
          f.write(res.content)
    else:
        dow()
#验证
def yanzhengma():
     #获取验证码
     dow()
     # 1 2 3 4 5 6 7 8
     xylist=[\'35,35\',\'105,35\',\'175,35\',\'245,35\',\'35,105\',\'105,105\',\'175,105\',\'245,105\']
     print(\'请依次输入验证码的位置并换行,0表示结束\')
     ilist=[]
     while True:
        i=input()
        if i==\'0\':
            break
        ilist.append(xylist[int(i)-1])
     xy=\',\'.join(ilist)
     print(xy)

     data={
         \'answer\':xy,
         \'login_site\':\'E\',
         \'rand\':\'sjrand\'
     }
     url=\'https://kyfw.12306.cn/passport/captcha/captcha-check\'
     requests.packages.urllib3.disable_warnings()
     res=self.post(url,data=data)
     print(res.url)
     print(res.text)
     code=re.search(\'_code.*?(\d)\',res.text,re.S).group(1)

     print(code)

     # 成功返回True,失败递归调用
     if code==\'4\':
         print(\'验证成功,请登陆\')

     elif code==\'5\':
         print(\'验证错误\')
         yanzhengma()
     elif code==\'7\':
         print(\'验证超时\')
         yanzhengma()
     else:
         print(\'验证失败\')
         yanzhengma()
def login():
     yanzhengma()#验证码
     data={
         \'username\':\'账号,
         \'password\':\'密码,
         \'appid\':\'otn\'
     }
     url=\'https://kyfw.12306.cn/passport/web/login\'
     requests.packages.urllib3.disable_warnings()
     res=self.post(url,data=data)
     print(res.text)
     code=re.search(\'_code.*?(\d)\',res.text,re.S).group(1)


     # 成功返回True,失败递归调用
     if code==\'0\':
         yzdata={
         \'appid\':\'otn\'
         }
         tk_url=\'https://kyfw.12306.cn/passport/web/auth/uamtk\'
         resp3=self.post(tk_url,data=yzdata)
         print(\'-----------------第一次验证-----------------\')
         print(resp3.text)
         login_message=resp3.json()[\'newapptk\']
         print(\'loginMessage=\',login_message)
         yz2data={
             \'tk\':login_message
         }
         client_url=\'https://kyfw.12306.cn/otn/uamauthclient\'
         resp4=self.post(client_url,data=yz2data)
         print(\'-----------------第二次验证-----------------\')
         print(resp4.text)
         print(\'登陆成功,可以开始购票\')

     elif code==\'1\':
         print(\'密码输入错误。如果输错次数超过4次,用户将被锁定。\')
         login()
     else:

         print(\'登录失败\')
         login()
def shoppiao():

    data={
       \'leftTicketDTO.train_date\':\'2018-10-15\',#时间
        \'leftTicketDTO.from_station\':\'BJQ\',#出发站码
        \'leftTicketDTO.to_station\':\'CBN\',#目的地码
        \'purpose_codes\':\'ADULT\'#票类型ADULT成人,STUDENT学生
    }
    url=\'https://kyfw.12306.cn/otn/leftTicket/queryA?\'
    requests.packages.urllib3.disable_warnings()
    res=self.get(url,params=data)
    print(res.status_code)
    print(res.text)
    dictr=json.loads(res.text)
    pklist=dictr.get(\'data\').get(\'result\')
    for item in pklist:
        sp_item = item.split(\'|\')
        for index, item in enumerate(sp_item,0):

            print(\'{}:\t{}\'.format(index, item))
        \'\'\'
        通过分析
        0:列车信息(订票时候需要) 1:信息 2:火车编号
        3:列车号 4:始发站   5:终点站   6:起始站  7:目标站    8:出发时间       9:到达时间
        10:行车时间
        11:有3种状态:Y, N, IS_TIME_NOT_BUY 分别对应,可以预定,不可以预定,其他原因----对应的是第1项
        12:参数leftTicket
        13:日期
        14:
        15:参数train_location
        21:高级动卧   22:        23:软卧 24:软座  25:特等座  26:无座 28:硬卧  29:硬座  30:二等座  31:一等座  32:商务座 33:动卧
       \'\'\'
        if sp_item[11]==\'Y\':#可以买票,开始订票
            if sp_item[30]!=\'无\':#买二等座
                print(sp_item[30])
                if vel_longin_2():#验证登陆
                   print(\'已经登陆可以开始下单\')
                   self.headers[\'X-Requested-With\']=\'XMLHttpRequest\'
                   secretStr=urllib.parse.unquote(sp_item[0])


                   self.headers[\'Referer\'] = \'https://kyfw.12306.cn/otn/leftTicket/init\'

                   submitOrderRequest(secretStr)

                   data = OrderedDict()
                   data["_json_att"] =\'\'
                   data["fromStationTelecode"] =sp_item[6]
                   data["leftTicket"] = sp_item[12]
                   data[\'purpose_codes\']=\'00\'
                   data[\'REPEAT_SUBMIT_TOKEN\']=\'\'
                   data["seatType"] = \'O\'
                   data["stationTrainCode"] = sp_item[3]
                   data["toStationTelecode"] =sp_item[7]
                   data["train_date"] = str(datetime.datetime.strptime(sp_item[13], \'%Y%m%d\').strftime(\'%a %b %d %Y %H:%M:%S GMT+0800\'))
                   data["train_location"] = sp_item[15]
                   data["train_no"] =sp_item[2]

                   \'\'\'
                   data={
                        \'train_date\':str(datetime.datetime.strptime(sp_item[13], \'%Y%m%d\').strftime(\'%a %b %d %Y %H:%M:%S GMT+0800\')),
                        \'train_no\':sp_item[2],#火车编号
                        \'stationTrainCode\':sp_item[3],#列车号
                        \'seatType\':\'O\',#座位类型 1是硬座(无座),2是软座,3是硬卧,4是软卧,  O 大写字母  是高铁二等座,M是高铁一等座,商务座(9),特等座(P),高级软卧(6)
                       \'fromStationTelecode\':sp_item[6],#起始站编号
                        \'toStationTelecode\':sp_item[7],#目标站编号
                        \'leftTicket\':sp_item[12],
                        \'train_location\':sp_item[15],#15项Q6
                   }
                \'\'\'
                   shopdin(data)

                else:
                    login()
                    shoppiao()
        break

def submitOrderRequest(secretStr):
    data = OrderedDict()
    data["secretStr"] = secretStr
    data["train_date"] = \'2018-09-20\'
    data["tour_flag"] = "dc"
    data["purpose_codes"] = "ADULT"
    data["query_from_station_name"] =\'深圳\'
    data["query_to_station_name"] = \'赤壁\'
    data["undefined"] = \'\'
    url=\'https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest\'
    res=self.post(url,data=data)
    print(res.text)
#开始下单
def shopdin(data1):
    #获取1个参数
    liop=initDc()
     #改变Headers
    self.headers[\'Referer\'] = \'https://kyfw.12306.cn/otn/confirmPassenger/initDc\'
    self.headers[\'Origin\']=\'https://kyfw.12306.cn\'
    print(self.headers)
    #请求并获取联系人参数
    pasdir=PassengerDTOs(liop[0])
    print(type(pasdir))
    # 二等座 0  (车票类型:ticket_type_codes 成人票1)      ,1,张三(passenger_name),   1(证件类型:passenger_id_type_code),320xxxxxx(passenger_id_no),151xxxx(mobile_no),N
    passengerTicketStr=data1[\'seatType\']+ \',0,\'+pasdir[\'passenger_type\']+\',\'+pasdir[\'passenger_name\']+\',\'+pasdir[\'passenger_id_type_code\']+\',\'+pasdir[\'passenger_id_no\']+\',\'+pasdir[\'mobile_no\']+\',N\'
    #张三(passenger_name),1(证件类型:passenger_id_type_code),320xxxxxx(passenger_id_no),1(passenger_type)_
    oldPassengerStr=pasdir[\'passenger_name\']+\',\'+pasdir[\'passenger_id_type_code\']+\',\'+pasdir[\'passenger_id_no\']+\',\'+pasdir[\'passenger_type\']+\'_\'
    data = OrderedDict()
    data["_json_att"] =\'\'
    data["ed_level_order_num"] =\'000000000000000000000000000000\'
    data["cancel_flag"] =\'2\'
    data["oldPassengerStr"] = oldPassengerStr
    data["passengerTicketStr"] = passengerTicketStr
    data["randCode"] =\'\'
    data["tour_flag"] =\'dc\'
    data["whatsSelect"] =\'1\'
    \'\'\'
    data={
        \'cancel_flag\':\'2\',#固定
        \'ed_level_order_num\':\'000000000000000000000000000000\',#固定
        \'passengerTicketStr\':passengerTicketStr,#联系人
        \'oldPassengerStr\':oldPassengerStr,#联系人
        \'tour_flag\':\'dc\',#单程
        \'randCode\':\'\',#空
        \'whatsSelect\':\'1\',#是否选择了联系人,
    }
    \'\'\'
    OrderInfo(data)
    data1[\'REPEAT_SUBMIT_TOKEN\']=liop[0]
    #提交订单
    getQueueCount(data1)
    data2= OrderedDict()
    data2["_json_att"] =\'\'#空
    data2["choose_seats"] =\'\'#空
    data2["dwAll"] =\'N\'#固定
    data2["key_check_isChange"] =liop[1]#页面找
    data2["leftTicketStr"] = data1[\'leftTicket\']#列车
    data2["oldPassengerStr"] =oldPassengerStr#联系人
    data2["passengerTicketStr"] =passengerTicketStr#联系人
    data2["purpose_codes"] =\'00\'#
    data2["randCode"] =\'\'#随机数 空
    data2["REPEAT_SUBMIT_TOKEN"] =liop[0]
    data2["roomType"] =\'00\'#固定
    data2["seatDetailType"] =\'000\'#选铺 暂不支持 默认参数
    data2["train_location"] = data1[\'train_location\']#q6
    data2["whatsSelect"] =\'1\'#固定
    tijiao(data2)
def tijiao(data):
    url=\'https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue\'
    res=self.post(url,data=data)
    print(res.status_code)
    print(res.text)
#获取联系人
def PassengerDTOs(REPEAT_SUBMIT_TOKEN):
    data={
        \'_json_att\':\'\',#空
        \'REPEAT_SUBMIT_TOKEN\':REPEAT_SUBMIT_TOKEN#页面找
    }
    url=\'https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs\'
    res=self.post(url,data=data)
    #print(res.text)
    passen=res.json().get(\'data\').get(\'normal_passengers\')[1]
    print(passen)
    return passen

#订单页面----获取参数
def initDc():
    url=\'https://kyfw.12306.cn/otn/confirmPassenger/initDc\'
    res=self.post(url,data={\'_json_att\':\'\'})
    REPEAT_SUBMIT_TOKEN=re.search(\'globalRepeatSubmitToken = .(.*?).;\',res.text,re.S).group(1)
    ticketInfoForPassengerForm_name = re.compile(r\'var ticketInfoForPassengerForm=(\{.+\})?\')
    order_request_params_name = re.compile(r\'var orderRequestDTO=(\{.+\})?\')
    re_tfpf = re.findall(ticketInfoForPassengerForm_name, res.text)
    re_orp = re.findall(order_request_params_name, res.text)
    key_check_isChange=re.search(\'key_check_isChange.:.(.*?).,\',res.text,re.S).group(1)
    return [REPEAT_SUBMIT_TOKEN,key_check_isChange]
 #选乘客票种提交
def OrderInfo(data):
    url=\'https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo\'
    res=self.post(url,data=data)
    print(res.status_code)
    print(res.text)
#提交订单列车余票。
def getQueueCount(data):
    url=\'https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount\'
    res=self.post(url,data=data)
    print(res.status_code)
    print(res.text)
def vel_longin_2():
    url=\'https://kyfw.12306.cn/otn/login/checkUser\'
    requests.packages.urllib3.disable_warnings()
    res=self.post(url,data={\'_json_att\':\'\'})
    login_vel=res.json().get(\'data\')[\'flag\']

    return login_vel
if __name__ == \'__main__\':
    #yanzhengma()
    shoppiao()
    vel_longin_2()

 

  

 

分类:

技术点:

相关文章: