12306抢票脚本加页面显示+类封装

import json
import time
from selenium import webdriver#导入模块
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.service import Service#选择浏览器
from selenium.webdriver import Keys
import  requests
import prettytable as pt#可视化
import tkinter as tk

class Tkgui():
    f = open('城市编号.json', encoding='utf-8')
    txt = f.read()  # 读文件JSON
    json_data = json.loads(txt)  # 将JSON转成字典
    root = tk.Tk()
    root.title('火车票菜单')
    root.geometry('400x240')
    # 日期文本输入框
    labelName = tk.Label(root, text='输入出发日期(格式:2023-12-07):', justify=tk.RIGHT, anchor='e', width=80,
                         bg='grey')
    labelName.place(x=-10, y=5, width=220, height=20)
    varName = tk.StringVar(root, value='')
    entryName = tk.Entry(root, width=80, textvariable=varName)
    entryName.place(x=220, y=5, width=80, height=20)
    data = varName.get()

    # 出发地文本,文本输入框
    labelPwd = tk.Label(root, text='输入出发地:', justify=tk.RIGHT, anchor='e', width=80, bg='grey')
    labelPwd.place(x=130, y=30, width=80, height=20)
    varPwd = tk.StringVar(root, value='')
    entryPwd = tk.Entry(root, width=40, textvariable=varPwd)
    entryPwd.place(x=220, y=30, width=80, height=20)
    from_station = varPwd.get()

    # 到达地文本输入框
    varPwd1 = tk.StringVar(root, value='')
    labelPwd1 = tk.Label(root, text='输入到达地:', justify=tk.RIGHT, anchor='e', width=80, bg='grey')
    labelPwd1.place(x=130, y=60, width=80, height=20)
    # varPwd2 = tk.StringVar(self.root , value='')
    entryPwd2 = tk.Entry(root, width=80, textvariable=varPwd1)
    entryPwd2.place(x=220, y=60, width=80, height=20)
    to_station = varPwd1.get()


    def __init__(self):
        # self.root=self.root
        # self.entryName=self.entryName
        # self.entryPwd=self.entryPwd
        # self.entryPwd2=self.entryPwd2
        # self.json_data=self.json_data
        self.buttonque()
        self.root.mainloop()




    def quire(self):

        queserdata = f'https://kyfw.12306.cn/otn/leftTicket/queryE?leftTicketDTO.train_date={self.data}&leftTicketDTO.from_station={self.json_data[self.from_station]}&leftTicketDTO.to_station={self.json_data[self.to_station]}&purpose_codes=ADULT'
            # f'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={data}&leftTicketDTO.from_station={self.json_data[from_station]}&leftTicketDTO.to_station={self.json_data[to_station]}&purpose_codes=ADULT'

        hearders = {'User-Agent':
                        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0',
                    'Cookie': 'JSESSIONID=2CF49749DC413EB771E2BD5AD7744F9D; BIGipServerpassport=870842634.50215.0000; guidesStatus=off; highContrastMode=defaltMode; cursorStatus=off; route=495c805987d0f5c8c84b14f60212447d; BIGipServerotn=1691943178.50210.0000; _jc_save_fromStation=%u5317%u4EAC%2CBJP; _jc_save_toStation=%u4E0A%u6D77%2CSHH; _jc_save_fromDate=2023-12-24; _jc_save_toDate=2023-12-24; _jc_save_wfdc_flag=dc'
                    }
        # res = requests.get(url=queser,headers=hearders)
        resdata = requests.get(url=queserdata, headers=hearders)
        resdata.encoding='utf8'

        mapdata = resdata.json()['data']['map']

        tb = pt.PrettyTable()
        tb.field_names = [
            '序号',
            '出发日期',
            '车次',
            '起始地',
            '终点地',
            '出发时间',
            '到达时间',
            '耗时',
            '软卧',
            '硬卧',
            '硬座',
            '无座',
            '一等座',
            '二等座',
        ]  # 显示表头

        conut = 1
        for index in resdata.json()['data']['result']:
            info = index.split('|')
            num = info[3]  # 车次
            start = info[6]  # 起始地
            end = info[7]  # 终点地
            start_time = info[8]  # 出发时间
            end_time = info[9]  # 到达间
            user_time = info[10]  # 耗时
            soft_sleeper = info[23]  # 软卧
            hard_sleeper = info[28]  # 硬卧
            hard_seat = info[29]  # 硬座
            no_seat = info[26]  # 无座
            first_class = info[31]  # 一等座
            second_calss = info[30]  # 二等座
            serial = conut * 2 - 1
            start_list = []  # 开始站
            end_list = []  # 起始站
            for key, value in mapdata.items():  # 将发车地还原
                if key == start:
                    start_list.append(value)
                    start = start_list[0]

                for key, value in mapdata.items():  # 将终点地还原
                    if key == end:
                        end_list.append(value)
                        end = end_list[0]

            dic = {'序号': serial,
                   '出发日期': self.data,
                   '车次': num,
                   '起始地': start,
                   '终点地': end,
                   '出发时间': start_time,
                   '到达时间': end_time,
                   '耗时': user_time,
                   '软卧': soft_sleeper,
                   '硬卧': hard_sleeper,
                   '硬座': hard_seat,
                   '无座': no_seat,
                   '一等座': first_class,
                   '二等座': second_calss,
                   }
            tb.add_row([
                serial,
                self.data,
                num,
                start,
                end,
                start_time,
                end_time,
                user_time,
                soft_sleeper,
                hard_sleeper,
                hard_seat,
                no_seat,
                first_class,
                second_calss
            ])
            conut = conut + 1
        print(tb)

        return self.data,self.from_station,self.to_station

    def buttonque(self):
        buttonOk = tk.Button(self.root, text='查询',command=self.quire)#调用查询函数
        buttonOk.place(x=200, y=90, width=50, height=20)
        bquit=tk.Button(self.root, text='退出', command=self.root.quit)
        bquit.place(x=250, y=90, width=50, height=20)


class Grabtickets():

        # t=Tkgui()
        # self.data,self.from_station,self.to_station=t.quire()
    def Ticket(self,from_station):
        # t=Tkgui()
        # self.data = t.entryName.get()
        # self.from_station = t.entryPwd.get()
        # self.to_station = t.entryPwd2.get()
        #

        number = input('请输入你要购买的票的序号')
        self.number = int(number)
        s = Service(executable_path=r"C:\Users\19604\PycharmProjects\pythonProject\DSF\12306抢票脚本\driver\geckodriver.exe")
        self.driver =webdriver.Firefox(service=s)#实例化浏览器对象 (后面用来操作)
        self.driver.implicitly_wait(20)#隐式等待20秒
        # self.driver = self.driver.implicitly_wait(5)

        self.driver.get('https://kyfw.12306.cn/otn/resources/login.html')#登入
        time.sleep(2)
        self.driver.find_element(By.XPATH,'//body/div/div[2]/div[2]/ul/li[2]/a').click()#点击扫描登录
        time.sleep(20)
        self.driver.forward()#页面刷新
        time.sleep(1)
        self.driver.find_element(By.LINK_TEXT,"首页").click()#点击首页
        self.driver.find_element(By.ID,'fromStationText').click()#定位到输入框
        time.sleep(1)
        self.driver.find_element(By.ID,'fromStationText').send_keys(from_station)#输入搜索的文字
        time.sleep(1)
        data_xiala =self.driver.find_element(By.XPATH,"//div[@id='panel_cities']").text#获取页面下拉框的数据
        list_data = data_xiala.split('\n')#根据空格分割成列表
        return list_data,number

    def data_analysis(self, list_data,input_data):
        list_data=list(list_data)#变成列表
        a=list_data[::2]#使用切片将拼音元素去除
        print(a)
        if len(a)<1:#返回的值小于切片的步长
            self.driver.find_element(By.XPATH, "//div[@id='panel_cities']/div[@id='citem_0']/span[1]").click()  # xpath定位到第一排
        else:
            indices= [k for k,v,in enumerate(a)if v==(input_data)]#判定输入的值和列表对比,返回一个下标
            return indices#返回下标

    def start_end(self,indices,number,to_station,data):
        self.driver.find_element(By.XPATH,f"//div[@id='panel_cities']/div[@id='citem_{indices[0]}']/span[1]").click()#定位指定的下标点击出发地点
        self.driver.find_element(By.ID,'toStationText').send_keys(to_station)#输入出发的地点
        data_xiala1 = self.driver.find_element(By.XPATH,"//div[@id='panel_cities']").text#获取到达下拉框数据
        print(data_xiala1)
        list_data_to_station=data_xiala1.split('\n')
        a=Grabtickets()
        indices1=a.data_analysis(list_data_to_station,input_data=to_station)    #获取到达的下标a
        self.driver.find_element(By.XPATH,f"//div[@id='panel_cities']/div[@id='citem_{indices1[0]}']/span[1]").click()#定位指定的下标点击到达地点
        self.driver.find_element(By.ID,"train_date").clear()#清空原来的日期
        self.driver.find_element(By.ID,"train_date").send_keys(data)#输入日期
        self.driver.find_element(By.ID,"train_date").send_keys(Keys.ENTER)#点击回车确认
        self.driver.find_element(By.XPATH,"//div/a[@id='search_one']").click()#点击查票
        for handle in self.driver.window_handles:#切换窗口
            self.driver.switch_to.window(handle)
            time.sleep(4)
            text_data=self.driver.find_elements(By.XPATH,f"//tbody[@id='queryLeftTable']/tr{[number]}/td[13]/a[@class='btn72']")  #点击预定
            if len(text_data)!=0:    #存在元素
                self.driver.find_element(By.XPATH, f"//tbody[@id='queryLeftTable']/tr{[number]}/td[13]/a[@class='btn72']").click()
                break
        #判断是否有弹窗有弹窗则超过了23:00无法订票,提示隔天5:00以后订票,没有弹窗则选择勾选联系人购票
        self.driver.find_element(By.ID,"normalPassenger_0").click()#勾选乘车人
        self.driver.find_element(By.LINK_TEXT,'提交订单').click()#提交订单
        time.sleep(2)
        self.driver.find_element(By.XPATH,'//div[@id="confirmDiv"]/a[2]').click()#点击确认

if __name__ == '__main__':
    data,from_station,to_station = Tkgui().quire()
    g=Grabtickets()
    list_data,number=g.Ticket(from_station)
    indices=g.data_analysis(list_data,from_station)
    g.start_end(indices,number,to_station,data)

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值