使用Selenium和Python自动预订车票

2023-09-17 16:29:50

在本文中,我们将探讨如何使用Selenium和Python自动预订车票。我们将以12306.cn网站为例,演示自动化预订车票的过程。通过阅读本文,您将更好地了解如何使用Selenium与网页进行交互。

准备工作

首先,我们需要安装Selenium库。您可以使用以下命令在您的Python环境中安装Selenium:
shell
pip install selenium
我们还需要下载适用于您的浏览器版本的chromedriver.exe。您可以从以下链接下载chromedriver.exe:chromedriver下载地址

代码解析

首先,让我们导入所需的库和模块:

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from config import Config
from selenium.webdriver.common.keys import Keys
import time
import select
接下来,我们定义了一个函数 `isElementExist` ,用于判断元素是否存在:
def isElementExist(driver):
    flag=True
    ele = driver.find_elements(by=By.CLASS_NAME, value='btn72')
    if len(ele) == 0:
        flag = False
        return flag
    if len(ele) == 1:
        return flag
    else:
        flag = False
        return flag

然后,我们定义了一个函数 get_ticket ,用于预订车票:

def get_ticket(conf, driver, url):
    driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": """Object.defineProperty(navigator, 'webdriver', {
          get: () => undefined})"""})
    driver.maximize_window()
    driver.get(url)
    driver.implicitly_wait(5)

    login = driver.find_element(by=By.ID, value='J-btn-login')
    login.click()
    driver.implicitly_wait(10)

    username_tag = driver.find_element(by=By.ID, value='J-userName')
    username_tag.send_keys(conf.username)
    password_tag = driver.find_element(by=By.ID, value='J-password')
    password_tag.send_keys(conf.password)
    login_now = driver.find_element(by=By.ID, value='J-login')
    login_now.click()
    time.sleep(20)

    driver.find_element(by=By.XPATH, value='//*[@id="link_for_ticket"]').click()
    driver.implicitly_wait(10)

    driver.find_element(by=By.XPATH, value='//*[@id="fromStationText"]').click()
    driver.find_element(by=By.XPATH, value='//*[@id="fromStationText"]').clear()
    driver.find_element(by=By.XPATH, value='//*[@id="fromStationText"]').send_keys(conf.fromstation)
    time.sleep(1)
    driver.find_element(by=By.XPATH, value='//*[@id="fromStationText"]').send_keys(Keys.ENTER)

    destination_tag = driver.find_element(by=By.XPATH, value='//*[@id="toStationText"]')
    destination_tag.click()
    destination_tag.clear()
    destination_tag.send_keys(conf.destination)
    time.sleep(1)
    destination_tag.send_keys(Keys.ENTER)
    driver.implicitly_wait(5)

    date_tag = driver.find_element(by=By.XPATH, value='//*[@id="train_date"]')
    date_tag.click()
    date_tag.clear()
    date_tag.send_keys(conf.date)
    time.sleep(1)
    query_tag = driver.find_element(by=By.XPATH, value='//*[@id="query_ticket"]')

    start = time.time()

    while True:
        driver.implicitly_wait(5)
        driver.execute_script("$(arguments[0]).click()", query_tag)

        if not isElementExist(driver):
            print(f"15点30分起售,现在是{time.strftime('%H:%M:%S', time.localtime())},还未开始售票")
            if time.time() - start >= 120:
                driver.refresh()
                start = time.time()
            time.sleep(1)
            continue

        tickets = driver.find_elements(by=By.XPATH, value='//*[@id="queryLeftTable"]/tr')
        tickets = [tickets[i] for i in range(len(tickets) - 1) if i % 2 == 0]
        
        for ticket in tickets:
            if ticket.find_element(by=By.CLASS_NAME,value='number').text == conf.trainnumber and ticket.find_element(by=By.XPATH, value='//td[8]').text != "候补":
                ticket.find_element(by=By.CLASS_NAME, value='btn72').click()
                driver.find_element(by=By.XPATH, value='//*[@id="normalPassenger_0"]').click()
                driver.find_element(by=By.XPATH, value='//*[@id="submitOrder_id"]').click()
                driver.find_element(by=By.XPATH, value='//html/body/div[5]/div/div[5]/div[1]/div/div[2]/div[2]/div[3]/div[2]/div[2]/ul[2]/li[2]/a[@id="1F"]').click()
                driver.find_element(by=By.XPATH, value='//html/body/div[5]/div/div[5]/div[1]/div/div[2]/div[2]/div[8]/a[2][@id="qr_submit_id"]').click()
                print(f"{conf.trainnumber}次列车抢票成功,请尽快在10分钟内支付!")
                return

最后,我们使用了 Config 类来保存有关车票的配置信息,并在 main 函数中调用 get_ticket 函数来执行预订车票的操作:

if __name__ == '__main__':
    conf = Config()

    url = 'https://www.12306.cn/index/'

    driver = webdriver.Chrome()
    get_ticket(conf, driver, url)
    time.sleep(10)
    driver.quit()

结论

本文介绍了如何使用Selenium和Python自动预订车票。通过编写代码,我们可以自动化处理登录、预订车票等操作,从而节省时间和精力。希望本文对您有所帮助,谢谢阅读!

更多推荐

使用Git把项目上传到Gitee的详细步骤

1.到Git官网下载并安装2.到Gitee官网进行注册,然后在Gitee中新建一个远程仓库3.设置远程仓库的参数4.返回Gitee查看仓库是否生成成功5.新建一个文件夹作为你的本地仓库6.将新建好的文件夹初始化成本地仓库第一步:右键点击刚创建的本地仓库,然后点击GitBashHere第二步:在命令行里输入gitinit

八、【漏洞复现】jupyter-notebook 命令执行(CVE-2019-9644)

8.0、基础知识1、测试功能点(这种情况基本上很难遇到)8.1、漏洞原理​JupyterNotebook是一套用于创建、共享代码和说明性文本文档的开源Web应用程序。JupyterNotebook可直接使用命令行执行任意命令。​8.2、影响范围未授权开启终端权限的系统8.3、指纹识别1.有主页与明显logo主页:log

常见web漏洞原理整理

文章目录一、SQL注入1.1SQL注入漏洞原理1.2SQL注入的两个关键点1.3与Mysql注入相关的知识点1.4SQL注入的主要分类1.5SQL注入的流程1.5.1普通SQL注入1.5.2盲注1.6SQL注入总结二、文件上传2.1文件上传漏洞原理2.2客户端检测及绕过(JS检测与绕过)2.3服务端检测2.3.1后缀名

力扣常见算法题

LeetCode上的问题可以有很多不同的解题思路,具体的解法取决于问题的要求和限制条件。以下是一些常见的解题思路和Python代码示例:文章目录思路1.暴力法(BruteForce):2.哈希表(HashTable):3.双指针(TwoPointers):4.动态规划(DynamicProgramming):例题1.两

【第43篇】CLIP:从自然语言监督中学习可迁移的视觉模型

摘要最先进的计算机视觉系统被训练来预测一组固定的预定对象类别。这种受限制的监督形式限制了它们的通用性和可用性,因为需要额外的标记数据来指定任何其他视觉概念。直接从有关图像的原始文本中学习是一种很有前途的替代方案,它利用了更广泛的监督来源。我们证明了预测哪个标题与哪个图像搭配的简单预训练任务是一种有效且可扩展的方式,可以

华纳云:Ubuntu中怎么配置lamp环境

LAMP(Linux、Apache、MySQL、PHP)是一种常用于搭建Web服务器的开发环境。在Ubuntu中配置LAMP环境相对简单,以下是配置的基本步骤:安装ApacheWeb服务器:打开终端,运行以下命令安装Apache:sudoaptupdatesudoaptinstallapache2安装完成后,启动Apa

使用 PyTorch 的计算机视觉简介 (3/6)

一、说明在本单元中,我们将了解卷积神经网络(CNN),它是专门为计算机视觉设计的。卷积层允许我们从图像中提取某些图像模式,以便最终分类器基于这些特征。二、卷积神经网络计算机视觉不同于通用分类,因为当我们试图在图片中找到某个物体时,我们正在扫描图像以寻找一些特定的图案及其组合。比如在寻找猫的时候,我们首先可能会寻找水平线

​重生奇迹MU魔剑士玩转攻略​

大家都知道重生奇迹MU中有很多职业,比如魔法师、弓箭手、剑士等等,并且后续版本又推出了其他职业。根据职业加点不同又有很多方向,像魔剑士便是剑士的一个发展分支。如何玩好奇迹魔剑士?那么玩魔剑士应该怎么玩呢,我们玩家应该怎么去好游戏之中的魔剑士呢,在加点方面需要注意什么呢,这些问题对于每一个玩家都应该思考一下。如果玩家想要

绘图(一)弹球小游戏

AWT编程·语雀仓库:Java图形化界面:Java图形化界面学习demo与资料(gitee.com)很多程序如各种小游戏都需要在窗口中绘制各种图形,除此之外,即使在开发JavaEE项目时,有时候也必须"动态"地向客户端生成各种图形、图表,比如图形验证码、统计图等,这都需要利用AWT的绘图功能。组件绘图原理之前我们已经学

高通8295中国首发!智舱再度上演「军备竞赛」,这次有何不同

对于智能座舱来说,上一轮市场红利已经接近尾声。高工智能汽车研究院监测数据显示,2023年1-6月中国市场(不含进出口)乘用车前装标配中控娱乐系统交付856.13万辆,前装标配渗透率已经超过90%,达到92.13%。其中,支持车联网功能主机占比也已经超过80%,达到83.03%。这意味着,车企需要尽快构建下一代座舱的差异

“智能制造进园区·浙江站和专家行”活动成功举办

为进一步加强央地联动,强化智能制造系统推进格局,促进重点区域行业智能制造供需对接,2023年9月12日-15日,在工业和信息化部装备工业一司指导下,由国家智能制造专家委员会、浙江省经济和信息化厅、智能制造系统解决方案供应商联盟、中国电子技术标准化研究院、温州市人民政府主办,瑞安市人民政府、温州市经济和信息化局、浙江省技

热文推荐