selenium实现12306自动抢票脚本

文章目录

一、selenium介绍

二、流程步骤

        1.导入模块

        2.初始化

        3.GUI界面获取信息

        4.点击操作

        5.预定操作

        6.买票环节

一、 selenium介绍

Selenium 是一个流行的自动化测试工具,主要用于通过模拟用户操作来测试 Web 应用程序。它支持多种编程语言,并且可以在各种操作系统上运行。使用 Selenium,开发人员和测试人员可以编写自动化脚本,以便自动执行各种操作,如点击按钮、填写表单、提交数据等,从而验证 Web 应用程序的行为和功能是否符合预期。

二、流程步骤

1.导入模块

import tkinter
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
import time
import easygui as g
from selenium.webdriver.support.ui import Select
from lxml import etree
from tkinter import *
import re

通过python的第三方库tkinter收集用户的列车信息,从而实现自动化选择。
Chrom浏览器对应的chromdriver版本下载

2.初始化

填入相应的chromdriver位置

    def __init__(self):
        #chromedriver对应chrome版本是126.0.6478.63
        self.driver = webdriver.Chrome(executable_path='chromedriver-win64/chromedriver.exe')

3.GUI界面获取信息

输入出发地,目的地,时间,座位类型,车票类型以及乘车人姓名

 def input(self):
        """
        利用tkinter实现用户界面信息输入
        :return: None
        """
        global root
        global entryName1
        global entryName2
        global entryName3
        global entryName4
        global entryName5
        global entryName6
        root = tkinter.Tk()
        root.geometry("400x380+418+117")
        root.title("车票信息")
        labelName1 = Label(root, text='出发地:', justify=RIGHT, anchor='e', font=("黑体", 15))
        labelName1.place(x=50, y=60, width=120, height=20)
        varName1 = StringVar(root, value='')
        entryName1 = Entry(root, width=80, textvariable=varName1)
        entryName1.place(x=180, y=60, width=100, height=20)
        labelName2 = Label(root, text='目的地:', justify=RIGHT, anchor='e', font=("黑体", 15))
        labelName2.place(x=50, y=100, width=120, height=20)
        varName2 = StringVar(root, value='')
        entryName2 = Entry(root, width=80, textvariable=varName2)
        entryName2.place(x=180, y=100, width=100, height=20)
        labelName3 = Label(root, text='出发日期:', justify=RIGHT, anchor='e', font=("黑体", 15))
        labelName3.place(x=50, y=140, width=120, height=20)
        varName3 = StringVar(root, value='')
        entryName3 = Entry(root, width=80, textvariable=varName3)
        entryName3.place(x=180, y=140, width=100, height=20)
        labelName4 = Label(root, text='座位类型:', justify=RIGHT, anchor='e', font=("黑体", 15))
        labelName4.place(x=50, y=180, width=120, height=20)
        varName4 = StringVar(root, value='')
        entryName4 = Entry(root, width=80, textvariable=varName4)
        entryName4.place(x=180, y=180, width=100, height=20)
        labelName5 = Label(root, text='车票类型:', justify=RIGHT, anchor='e', font=("黑体", 15))
        labelName5.place(x=50, y=220, width=120, height=20)
        varName5 = StringVar(root, value='')
        entryName5 = Entry(root, width=80, textvariable=varName5)
        entryName5.place(x=180, y=220, width=100, height=20)
        labelName6 = Label(root, text='乘车人姓名:', justify=RIGHT, anchor='e', font=("黑体", 15))
        labelName6.place(x=50, y=260, width=120, height=20)
        varName6 = StringVar(root, value='')
        entryName6 = Entry(root, width=80, textvariable=varName6)
        entryName6.place(x=180, y=260, width=100, height=20)
        buttonOk = Button(root, text='确定', font=("黑体", 15), command=self.click_)
        buttonOk.place(x=140, y=300, width=50, height=25)
        root.mainloop()

4.点击操作

通过进入官网,查询要点击的id,写入程序,之后进入列车选择页面

    def click_(self):
        """
        进入官网,等待信息输入
        :return: None
        """
        #获取用户信息
        self.depart = entryName1.get()
        self.goal = entryName2.get()
        self.time_ = entryName3.get()
        self.sit = entryName4.get()
        self.type_ = entryName5.get()
        self.car_person = entryName6.get()
        # 关闭界面
        root.destroy()
        self.driver.get('https://www.12306.cn/index/index.html')
        #出发地
        tag1 = self.driver.find_element_by_id('fromStationText')
        tag1.clear()
        #目的地
        tag2 = self.driver.find_element_by_id('toStationText')
        tag2.clear()
        #出发时间
        tag3 = self.driver.find_element_by_id('train_date')
        tag3.clear()
        but3 = self.driver.find_element_by_id('search_one')
        button = ActionChains(self.driver)
        button.move_to_element(tag3).send_keys_to_element(tag3, self.time_)
        button.move_to_element(tag1)
        button.send_keys_to_element(tag1, self.depart)
        button.perform()
        tag_1 = self.driver.find_element_by_id('citem_0')
        #模拟用户点击,实例化一个行为链
        ActionChains(self.driver).move_to_element(tag_1).click(tag_1).perform()
        ActionChains(self.driver).move_to_element(tag2).send_keys_to_element(tag2, self.goal).perform()
        tag_2 = self.driver.find_element_by_id('citem_0')  # 不能用tag_1,id还未加载更新
        ActionChains(self.driver).move_to_element(tag_2).click(tag_2).perform()
        if self.type_ == '学生票':
            ActionChains(self.driver).move_to_element(self.driver.find_element_by_id('isStudentDan')).click().perform()
        time.sleep(1)
        ActionChains(self.driver).move_to_element(but3).click(but3).perform()
        self.buy()

5.预定操作

通过循环点击查询按钮以及刷新页面来实现预订车票(最好在放票前的1分钟运行程序)

    def buy(self):
        """
        购票页面
        :return: None
        """
        self.driver.switch_to_window(self.driver.window_handles[1])
        car_sit ,car_id,judge_sit  = 0,0,0
        if self.sit == '二等座':
            self.sit = "O"
            car_sit = 5
        if self.sit == '一等座':
            self.sit = "M"
            car_sit = 4
        if self.sit == '商务座':
            self.sit = "9"
            car_sit = 2
        if self.sit == '软卧':
            self.sit = '4'
            car_sit = 7
        if self.sit == '硬卧':
            self.sit = '3'
            car_sit = 8
        if self.sit == '硬座':
            self.sit = '1'
            car_sit = 10
        if self.sit == '软座':
            self.sit = '2'
            car_sit = 9
        while True:
            WebDriverWait(self.driver, 10).until(
                EC.presence_of_element_located((By.ID, "query_ticket"))
            )
            query_button = self.driver.find_element_by_id('query_ticket')#查询按钮
            self.driver.execute_script("arguments[0].click()", query_button)
            # query_button.click()#可能会出现不能点击问题
            self.driver.switch_to_window(self.driver.window_handles[1])
            book = self.driver.find_elements_by_class_name('btn72')#预定按钮
            if book[0].text != '预订':#车票未开售
                time.sleep(1)
                self.driver.refresh()
            else:#开售后取最近一趟列车
                for i in range(len(book)):
                    car_id = re.findall(r'span id="(.*?)"',
                        self.driver.find_element_by_xpath(r'//*[@class="train"]').get_attribute('innerHTML')
                    ,re.S)[0]#会获取标签之间的完整 html
                    judge_sit = self.driver.find_element_by_xpath('//*[@id='+'"'+"ticket_"+str(car_id)[0:18:]+'"'+']/td[' + str(car_sit) + ']')

                    if judge_sit.text != '--':#判断是否有座位
                        book[i].click()
                        WebDriverWait(self.driver,1000).until(
                            EC.presence_of_element_located((By.ID,'submitOrder_id'))
                        )#等待扫码登录
                        self.buy_detail()
                        break

                    else:
                        g.msgbox('无座了','提示')
                break
        time.sleep(30)#买票时间
        self.driver.quit()

6.买票环节

当预定成功时,登录12306的个人信息(最好扫码登录)购票。

    def buy_detail(self):
        """
        购票界面的一些相关信息填写
        :return:None
        """
        self.driver.switch_to_window(self.driver.window_handles[1])
        sel_but1 = Select(self.driver.find_element_by_id('ticketType_1'))
        sel_but1.select_by_visible_text(self.type_)
        sel_but2 = Select(self.driver.find_element_by_id('seatType_1'))
        sel_but2.select_by_value(self.sit)
        sel = self.driver.page_source
        txt = etree.HTML(sel)
        txt = txt.xpath('//*[@id="normal_passenger_id"]')
        j, ID = 1, 0
        for i in txt:
            if i.xpath('./li[' + str(j) + ']/label/text()')[0] == self.car_person:
                break
            j += 1
        for k in range(0, j):
            ID = 'normalPassenger_' + str(k)
        buton = self.driver.find_element_by_id(ID)
        buton.click()
        payment = self.driver.find_element_by_id('submitOrder_id')
        payment.click()

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值