春节临近了,小伙伴们都在忙着抢票了,很多人总是被各种乱七八糟的抢票程序误导,诱骗,不如自己用python写一个12306抢票脚本好了。

言归正传,有了需求自然就要实现。技术部分,抢票程序由selenium驱动chrome进行,主要分为几下几部分。(别问我为什么不直接用requests买,有点难0-0)

1.安装selenium和chromedriver

selenium包直接使用pip安装即可

    pip install selenium

安装chromedriver,进入http://chromedriver.storage.googleapis.com/index.htmlx下载最新内核,目前最新版本为2.45,下载解压缩并放在PATH下,windows直接放在C:/Windows/System32下,linux放在/usr/local/bin下即可,接下来使用下列python命令测试。 更新内容:最新版做了基本的适应,近几天再更新gui界面 

    #!env python
    from selenium import webdriver
    import time
    browser = webdriver.Chrome()#如果不在环境变量中,括号里写上绝对路径也行
    browser.get("https://www.bobobk.com")
    print(u"5秒后关闭程序")
    time.sleep(5)
    browser.close() 
《python3搭配selenium实现12306抢票程序》

可以看到浏览器已经成功打开指定页面

2.selenium登陆12306抢票

直接上代码,分几步,登陆,刷票,订购,选座,提交,成功后需要手动支付订单.

import time
import re
from scrapy.selector import Selector
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By

# main function
class main():
    def __init__(self):

        self.get_info()
        op = webdriver.ChromeOptions()
        op.add_argument("--window-size=1920,1080")
        #op.add_argument("--headless")
        op.add_experimental_option("excludeSwitches", ["enable-automation"])
        op.add_experimental_option("useAutomationExtension", False)
        prefs = {"credentials_enable_service": False,"profile.password_manager_enabled": False}
        op.add_experimental_option("prefs", prefs)
        self.browser = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=op)
        print("chrome ok")
        self.run()
    # basic info
    def get_info(self):

        self.username = input("12306 username:")
        self.password = input("12306 pass:")
        self.from_station = input("initial:")
        self.to_station = input("target:")
        self.from_year = int(input("year:"))
        self.from_month = int(input("month:"))
        self.from_day = int(input("day:"))
        self.order = 0
        self.student = 0 # 0 for adult,1 for student
        self.login_check = "个人中心"
        self.ticketer = ""
        self.trainpick = input("train(like:G4729):")#"G1389"
        self.seat = input("seat(TZ special, ZY first, ZE second):")
        ## 
        self.login_url = "https://kyfw.12306.cn/otn/resources/login.html"
        self.query_url = "https://kyfw.12306.cn/otn/leftTicket/init"
        self.order_url = "https://kyfw.12306.cn/otn/view/train_order.html"

    # get train
    def get_train(self):
        print(self.browser.page_source)
        self.my_train_list = re.findall('datatran="({.+?})"',self.browser.page_source)
        
        self.my_ticket = [i for i in
                          Selector(text=self.browser.page_source).css("#queryLeftTable>tr::attr(id)").extract()
                          if "ticket" in i]
        print(f"we get ID:{'  '.join(self.my_ticket)}")
        for i in range(len(self.my_ticket)):
            element = self.browser.find_element(By.ID,self.my_ticket[i]).get_attribute('innerHTML')
            print(element)
        print("we get train:")
        for i in range(len(self.my_train_list)):
            print(f"{i + 1} {self.my_train_list[i]}")
    # check alert messagebox
    def check_alert(self,posi):
        try:
            if posi == 0:
                self.browser.find_element(By.XPATH,"//div[@class='modal']/div[@class='modal-ft']").send_keys(Keys.ENTER)
                
            if posi == 1:
                self.browser.find_element(By.ID,"gb_closeDefaultWarningWindowDialog_id").click()
            if posi == 2:
                self.browser.find_element(By.ID,"qd_closeDefaultWarningWindowDialog_id").click()
        except:
            pass
        time.sleep(0.1)
    # fulfill element
    def fill_input(self):
        self.check_alert(1)
        print("now we are trying to click fromstationtext")
        self.browser.find_element(By.ID,"fromStationText").click()
        time.sleep(0.1)
        self.browser.find_element(By.ID,"fromStationText").send_keys(Keys.BACKSPACE)
        self.browser.find_element(By.ID,"fromStationText").send_keys(self.from_station)
        self.browser.find_element(By.ID,"fromStationText").send_keys(Keys.ENTER)
        time.sleep(0.1)
        self.browser.find_element(By.ID,"toStationText").click()
        self.browser.find_element(By.ID,"toStationText").send_keys(Keys.BACKSPACE)
        self.browser.find_element(By.ID,"toStationText").send_keys(self.to_station)
        time.sleep(0.1)
        self.browser.find_element(By.ID,"toStationText").send_keys(Keys.ENTER)
        time.sleep(0.1)
        self.browser.find_element(By.ID,"train_date").click()
        time.sleep(0.1)
        self.browser.find_element(By.XPATH,"//div[@class='cal-wrap']//div[@class='year']/input").click()
        time.sleep(0.1)
        self.browser.find_element(By.XPATH,f"//div[@class='cal-wrap']//div[@class='year']/div/ul/li[{self.from_year-2016}]").click()
        time.sleep(0.1)
        self.browser.find_element(By.XPATH,"//div[@class='cal-wrap']//div[@class='month']/input").click()
        time.sleep(0.1)
        self.browser.find_element(By.XPATH,f"//div[@class='cal-wrap']//div[@class='month']/ul/li[{self.from_month}]").click()
        time.sleep(0.1)
        self.browser.find_element(By.XPATH,f"//div[@class='cal-wrap']//div[@class='cal-cm']/div[{self.from_day}]/div").click()
        if self.student:
            self.browser.find_element(By.ID,"sf2").click()
        time.sleep(0.1)
        self.browser.find_element(By.ID,"query_ticket").click()

    # get seat
    def get_seat(self, seatid):
        return (self.browser.find_element(By.ID,seatid).text != "--" and browser.find_element(By.ID,seatid).text != '无' and browser.find_element(By.ID,seatid).text != '候补')

    # booking ticket
    def booking(self, ticket_picked):
        print("start to booking")
        self.browser.find_element(By.ID,ticket_picked).find_element(By.CLASS_NAME,"btn72").click()
        time.sleep(0.1)
        self.check_alert(2)
        print("check passenger")
        self.browser.find_element(By.CLASS_NAME,"per-sel").find_element(By.ID,"normalPassenger_0").click()
        time.sleep(0.1)
        print("start to order ticket")
        self.browser.find_element(By.ID,"submitOrder_id").click()
        print("order complete")

    # check ticket order
    def check_order(self):
        self.browser.get(self.order_url)
        if self.trainpick in self.browser.page_source:
            self.order = 1
    # login function
    def login(self):
        # 点击当前页面的"登录"
        self.browser.get(self.login_url)
        time.sleep(2)
        if self.browser.current_url == self.login_url:
            # fill填充搜索框的内容,username。name=loginUserDTO.user_name的元素。
            self.browser.find_element(By.ID,"J-userName").send_keys(self.username)
            time.sleep(2)
            self.browser.find_element(By.ID,"J-password").send_keys(self.password)
            time.sleep(2)
            self.browser.find_element(By.ID,"J-login").click()
            time.sleep(5)
            # 登录手动输入验证码,并登录系统fromStationText
            for i in range(30):
                time.sleep(5)
                if self.login_check in self.browser.page_source:
                    self.check_alert(0)
                    return True
                    break
                i += 1
            
            return False
        else:
            return True
    def run(self):
        log_or_not = self.login()
        while not log_or_not:

            log_or_not = self.login()
        print("login successful")
        time.sleep(5)
        self.browser.get(self.query_url)
        time.sleep(0.1)
        self.check_alert(1)
        time.sleep(3)
        print("now trying to fill input")
        self.fill_input()
        time.sleep(0.1)
        self.get_train()
        time.sleep(0.1)
        count_query = 0
        while True:
            if self.order:
                break
            count_query += 1
            if count_query % 100 == 0:
                count_query = 0
                self.browser.get(self.query_url)
                self.check_alert(1)
            print(f"query times:{count_query}")
            try:
                if self.browser.current_url != self.query_url:
                    self.browser.get(self.query_url)
                    self.check_alert(1)
                    self.fill_input()
                self.browser.find_element(By.ID,"query_ticket").click()
                time.sleep(0.1)
                ticket_picked = self.my_ticket[self.my_train_list.index(self.trainpick)]
                seatid = self.seat + "_" + ticket_picked.split("_")[1]
                print(f"seatid:{seatid}")
                if self.get_seat(seatid):
                    print("ready to buy ticket")
                    self.booking(ticket_picked)
                    self.check_order()
                time.sleep(2)
                
            except:
                pass

            break
# start loop
if __name__ == "__main__":
    main()

使用pyqt增加图形界面,并添加提示信息: 使用前提,按需求pip安装需要的包,本地安装chrome浏览器,因为原理是使用selenium调用谷歌浏览器进行登录和抢票.为防止出现验证码信息,可先自行登录使其识别为常用地址,可避免验证码的出现.

import sys
import time

from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import (QLabel,QLineEdit,QTextEdit,QPlainTextEdit,
        QWidget,QApplication,QGridLayout,QHBoxLayout,QFormLayout,
        QRadioButton,QVBoxLayout,QPushButton)
from scrapy.selector import Selector
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from webdriver_manager.chrome import ChromeDriverManager


class main():
    #############chrome
    def __init__(self):
        self.op = webdriver.ChromeOptions()
        self.op.add_argument("--window-size=1920,1080")
        self.op.add_experimental_option("excludeSwitches", ["enable-automation"])
        self.op.add_experimental_option("useAutomationExtension", False)
        prefs = {"credentials_enable_service": False, "profile.password_manager_enabled": False}
        self.op.add_experimental_option("prefs", prefs)
        self.browser = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=self.op)
        ###################################start
        self.app = QApplication(sys.argv)
        self.win = QWidget()
        ##############debug info
        self.info1 = QTextEdit("")
        self.info1.setReadOnly(True)
        self.debuginfo = QHBoxLayout()
        self.debuginfo.addWidget(self.info1)
        ############debug end
        self.order = 0
        self.student = 0  # 0 for adult,1 for student
        self.login_check = u"个人中心"
        self.ticketer = ""
        self.login_url = "https://kyfw.12306.cn/otn/resources/login.html"
        self.query_url = "https://kyfw.12306.cn/otn/leftTicket/init"
        self.order_url = "https://kyfw.12306.cn/otn/view/train_order.html"
        self.userinfo1 = QLabel(u"用户名:")
        self.l1 = QLineEdit("")
        self.userinfo2 = QLabel(u"密码:")
        self.l2 = QLineEdit("")
        self.l2.setEchoMode(QLineEdit.EchoMode(2))
        self.userinfo3 = QLabel(u"起点:")
        self.l3 = QLineEdit(u"上海")
        self.userinfo4 = QLabel(u"终点:")
        self.l4 = QLineEdit(u"鹰潭")
        self.userinfo5 = QLabel(u"年:")
        self.l5 = QLineEdit("2022")
        self.userinfo6 = QLabel(u"月:")
        self.l6 = QLineEdit("1")
        self.userinfo7 = QLabel(u"日:")
        self.l7 = QLineEdit("29")
        self.userinfo8 = QLabel(u"车次:")
        self.l8 = QLineEdit("G1333")
        self.userinfo9 = QLabel(u"座位:")
        self.l9 = QLineEdit("ZE")
        self.userinfo10 = QLabel(u"选座:")
        self.l10 = QLineEdit("F")
        self.userinput = QFormLayout()
        self.userinput.addRow(self.userinfo1, self.l1)
        self.userinput.addRow(self.userinfo2, self.l2)
        self.userinput.addRow(self.userinfo3, self.l3)
        self.userinput.addRow(self.userinfo4, self.l4)
        self.userinput.addRow(self.userinfo5, self.l5)
        self.userinput.addRow(self.userinfo6, self.l6)
        self.userinput.addRow(self.userinfo7, self.l7)
        self.userinput.addRow(self.userinfo8, self.l8)
        self.userinput.addRow(self.userinfo9, self.l9)
        self.userinput.addRow(self.userinfo10, self.l10)
        self.hbox = QHBoxLayout()
        self.r1 = QRadioButton(u"成人")
        self.r1.setChecked(True)
        self.r2 = QRadioButton(u"学生")
        self.hbox.addWidget(self.r1)
        self.hbox.addWidget(self.r2)
        self.hbox.addStretch()
        self.userinput.addRow(QLabel(u"身份:"), self.hbox)
        self.confirm = QPushButton(u"确认")
        self.startr = QPushButton(u"预热")
        self.startloop = QPushButton(u"抢票")
        self.multit = QPushButton(u"重置")
        self.userinput.addRow(self.confirm, self.startr)
        self.userinput.addRow(self.startloop, self.multit)
        ############## userinput end
        self.confirm.clicked.connect(self.get_input)
        self.startr.clicked.connect(self.first_run)
        self.startloop.clicked.connect(self.go_loop)
        self.multit.clicked.connect(self.run_reset)
        ### main grid
        self.row1 = QVBoxLayout()
        self.infolabel = QLabel(u"用户信息输入栏:")
        self.row1.addWidget(self.infolabel)
        self.row1.addLayout(self.userinput)
        self.row2 = QVBoxLayout()
        self.debuglabel = QLabel(u"用户信息展示栏:")
        self.row2.addWidget(self.debuglabel)
        self.row2.addLayout(self.debuginfo)
        self.row3 = QVBoxLayout()
        self.weblabel = QLabel(u"日志窗口:")
        self.webinfo = QPlainTextEdit()  # QWebEngineView()
        self.webinfo.setReadOnly(True)
        self.row3.addWidget(self.weblabel)
        self.row3.addWidget(self.webinfo)
        self.row4 = QVBoxLayout()
        self.helpinfo = QPlainTextEdit(u"""点击确认锁定信息\n点击预热进行登陆并获取列车基本信息\n点击抢票开始刷新页面并自动抢票\n点击重置解除锁定
        \n座位中 ZE 表示 二等座\nSWZ 表示 商务座\nZY 表示 一等座\nGR 表示 高级软卧\n RW 表示 软卧
        \nSRRB 表示 动卧\nYW 表示 硬卧\nRZ 表示 软座\nYZ 表示 硬座\nWZ 表示 无座
        \n选座\n窗口A B C 过道  D F窗口
        """)
        self.helpinfo.setReadOnly(True)
        self.helplabel = QLabel(u"帮助信息:")
        self.row4.addWidget(self.helplabel)
        self.row4.addWidget(self.helpinfo)
        self.mylayout = QGridLayout()
        self.mylayout.addLayout(self.row1, 1, 1, 1, 1)
        self.mylayout.addLayout(self.row2, 1, 2, 1, 1)
        self.mylayout.addLayout(self.row3, 2, 1, 1, 1)
        self.mylayout.addLayout(self.row4, 2, 2, 1, 1)
        self.win.setLayout(self.mylayout)
        self.win.setWindowTitle("bobobk购票")
        self.win.setWindowIcon(QIcon('head.ico'))
        self.win.setStyleSheet("""
        QLabel {
        color: 'Green';
        }
        QPlainTextEdit  {color: 'blue';
        
        }
        """)
        self.win.show()
        sys.exit(self.app.exec())
    def run_reset(self):
        self.startloop.setEnabled(True)
        self.confirm.setEnabled(True)
        self.startloop.setEnabled(True)
        self.startr.setEnabled(True)
        self.l1.setEnabled(True)
        self.l2.setEnabled(True)
        self.l3.setEnabled(True)
        self.l4.setEnabled(True)
        self.l5.setEnabled(True)
        self.l6.setEnabled(True)
        self.l7.setEnabled(True)
        self.l8.setEnabled(True)
        self.l9.setEnabled(True)
        self.l10.setEnabled(True)
        self.r1.setEnabled(True)
        self.r2.setEnabled(True)
    def fill_input(self):
        self.check_alert(1)
        print("now we are trying to click fromstationtext")
        self.browser.find_element(By.ID, "fromStationText").click()
        time.sleep(0.1)
        self.browser.find_element(By.ID, "fromStationText").send_keys(Keys.BACKSPACE)
        self.browser.find_element(By.ID, "fromStationText").send_keys(self.sstation)
        self.browser.find_element(By.ID, "fromStationText").send_keys(Keys.ENTER)
        time.sleep(0.1)
        self.browser.find_element(By.ID, "toStationText").click()
        self.browser.find_element(By.ID, "toStationText").send_keys(Keys.BACKSPACE)
        self.browser.find_element(By.ID, "toStationText").send_keys(self.estation)
        time.sleep(0.1)
        self.browser.find_element(By.ID, "toStationText").send_keys(Keys.ENTER)
        time.sleep(0.1)
        self.browser.find_element(By.ID, "train_date").click()
        time.sleep(0.1)
        self.browser.find_element(By.XPATH, "//div[@class='cal-wrap']//div[@class='year']/input").click()
        time.sleep(0.1)
        self.browser.find_element(By.XPATH,
                                  f"//div[@class='cal-wrap']//div[@class='year']/div/ul/li[{self.year - 2016}]").click()
        time.sleep(0.1)
        self.browser.find_element(By.XPATH, "//div[@class='cal-wrap']//div[@class='month']/input").click()
        time.sleep(0.1)
        self.browser.find_element(By.XPATH,
                                  f"//div[@class='cal-wrap']//div[@class='month']/ul/li[{self.month}]").click()
        time.sleep(0.1)
        self.browser.find_element(By.XPATH,
                                  f"//div[@class='cal-wrap']//div[@class='cal-cm']/div[{self.day}]/div").click()
        if self.student:
            self.browser.find_element(By.ID, "sf2").click()
        time.sleep(0.1)
        self.browser.find_element(By.ID, "query_ticket").click()
    def echo_log(self,mystr):
        self.webinfo.appendPlainText(f"{mystr}")#{self.webinfo.toPlainText()}
    def check_alert(self, posi):
        try:
            if posi == 0:
                self.browser.find_element(By.XPATH, "//div[@class='modal']/div[@class='modal-ft']/a").send_keys(
                    Keys.ENTER)

            if posi == 2:
                self.browser.find_element(By.ID, "gb_closeDefaultWarningWindowDialog_id").click()
            if posi == 1:
                self.browser.find_element(By.ID, "qd_closeDefaultWarningWindowDialog_id").click()
        except:
            pass

        time.sleep(0.1)

    def check_order(self):
        self.browser.get(self.order_url)
        if self.train in self.browser.page_source:
            self.order = 1

    def login(self):
        # 点击当前页面的"登录"
        self.echo_log(u"开始登录12306")
        self.browser.get(self.login_url)
        time.sleep(0.2)
        self.browser.find_element(By.ID, "J-userName").send_keys(self.username)
        time.sleep(0.2)
        self.browser.find_element(By.ID, "J-password").send_keys(self.password)
        time.sleep(0.2)
        self.browser.find_element(By.ID, "J-login").click()
        time.sleep(0.2)
        # 登录手动输入验证码,并登录系统fromStationText
        for i in range(30):
            time.sleep(5)
            if self.login_check in self.browser.page_source:
                self.check_alert(0)
                self.echo_log(u"登录12306成功")
                return True
            i += 1
        self.echo_log(u"登录12306失败")
        return False

    def get_seat(self, seatid):
        return (self.browser.find_element(By.ID, seatid).text != "--" and self.browser.find_element(By.ID,
                                                                                                    seatid).text != u'无' and self.browser.find_element(
            By.ID, seatid).text != u'候补')

    def first_run(self):
        self.startr.setEnabled(False)
        self.get_input()
        log_or_not = self.login()
        while not log_or_not:
            log_or_not = self.login()
        #self.echo_log("login successful")
        time.sleep(0.5)
        self.browser.get(self.query_url)
        time.sleep(0.1)
        self.check_alert(0)
        time.sleep(3)
        self.echo_log(u"开始填入购票信息")
        self.fill_input()
        time.sleep(0.1)
        self.browser.find_element(By.ID, "query_ticket").click()
        time.sleep(0.1)
        self.get_train()
        time.sleep(0.1)

    def get_train(self):
        self.my_train_list = []
        self.echo_log(u"开始获取剩余车票")
        self.my_ticket = [i for i in
                          Selector(text=self.browser.page_source).css("#queryLeftTable>tr::attr(id)").extract()
                          if "ticket" in i]
        #self.echo_log(f"we get ID:{'  '.join(self.my_ticket)}")
        for i in range(len(self.my_ticket)):
            element = self.browser.find_element(By.ID, self.my_ticket[i]).get_attribute('innerHTML')
            self.my_train_list.append(
                Selector(text=element).css(f"#{self.my_ticket[i]}_train>div>a::text").extract_first())
        self.echo_log(u"当前列车:")
        for i in range(len(self.my_train_list)):
            self.echo_log(f"{i + 1} {self.my_train_list[i]}")
        self.echo_log(u"列车信息获取完毕")
        self.ticket_picked = self.my_ticket[self.my_train_list.index(self.train)]
        self.echo_log(f"期望购买的列车是:{self.ticket_picked}")

    def booking(self):
        self.echo_log(u"开始订购车票流程")
        self.browser.find_element(By.ID, self.ticket_picked).find_element(By.CLASS_NAME, "btn72").click()
        time.sleep(0.1)
        self.check_alert(2)
        self.echo_log(u"选择乘客")
        self.browser.find_element(By.CLASS_NAME, "per-sel").find_element(By.ID, "normalPassenger_0").click()

        

        time.sleep(0.5)
        self.echo_log(u"开始订购")
        self.browser.find_element(By.ID, "submitOrder_id").click()
        if u"繁忙" not in self.browser.page_source:
            time.sleep(0.5)
            self.echo_log(u"开始选座")
            self.browser.execute_script(f'document.getElementById("1{self.pickseat}").setAttribute("class","cur")')
            # self.browser.find_element(By.ID,"1F").setAttribute("class", "cur")
            time.sleep(0.1)
            self.echo_log(u"提交订单")
            self.browser.find_element(By.ID, "qr_submit_id").click()

            time.sleep(0.1)
            self.echo_log("订购流程完毕")
            self.check_order()

    def go_loop(self):
        self.startloop.setEnabled(False)
        self.confirm.setEnabled(False)
        self.get_input()
        count_query = 0
        while True:
            if self.order:
                break
            if count_query % 100 == 0:
                count_query = 0
                self.browser.get(self.query_url)
                self.check_alert(1)
                self.fill_input()
            self.browser.find_element(By.ID, "query_ticket").click()
            time.sleep(0.1)
            self.booking()

    def get_input(self):
        self.echo_log(u"开始获取用户信息!")
        self.l1.setEnabled(False)
        self.l2.setEnabled(False)
        self.l3.setEnabled(False)
        self.l4.setEnabled(False)
        self.l5.setEnabled(False)
        self.l6.setEnabled(False)
        self.l7.setEnabled(False)
        self.l8.setEnabled(False)
        self.l9.setEnabled(False)
        self.l10.setEnabled(False)
        self.r1.setEnabled(False)
        self.r2.setEnabled(False)
        self.confirm.setEnabled(False)
        self.username = self.l1.text()
        self.password = self.l2.text()
        self.sstation = self.l3.text()
        self.estation = self.l4.text()
        self.year = int(self.l5.text())
        self.month = int(self.l6.text())
        self.day = int(self.l7.text())
        self.train = self.l8.text()
        self.seat = self.l9.text()
        self.pickseat = self.l10.text()
        self.student = self.r2.isChecked()
        printinfo = f"""用户名:{self.username}\n起点:{self.sstation}
终点:{self.estation}\n年:{self.year}\n月:{self.month}\n日:{self.day}\n列车:{self.train}
座位:{self.seat}\n选座:{self.pickseat}\n学生:{self.student}"""
        self.info1.setText(printinfo)
        self.echo_log(u"获取用户信息结束!")
        


if __name__ == "__main__":
    main()

使用指南:

点击确认锁定信息 点击预热进行登陆并获取列车基本信息 点击抢票开始刷新页面并自动抢票 点击重置解除锁定

座位中 ZE 表示 二等座 SWZ 表示 商务座 ZY 表示 一等座 GR 表示 高级软卧 RW 表示 软卧

SRRB 表示 动卧 YW 表示 硬卧 RZ 表示 软座 YZ 表示 硬座 WZ 表示 无座

选座 窗口A B C 过道 D F窗口

《python3搭配selenium实现12306抢票程序》

总结

本程序使用selenium直接调用浏览器实现了12306刷票抢票的基本要求,在用户正确填写信息后就会自动刷新浏览器并在给定的车次和坐席间购买车票。

待提高:由于使用浏览器刷新,刷新频率受到js控制,想办法看能不能分流,在其他地方刷新页面,这里购买。后面会增加用户配置内容,而不是写进程序里,目前已经通过pyqt增加图形界面,使用更加友好.如果有其他建议,欢迎留言。