python无需验证码免登录12306抢票 --selenium(2)

news2025/7/10 15:47:56

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

@[TOC](python无需验证码免登录12306抢票 --selenium(2))


前言

提示:这里可以添加本文要记录的大概内容:

就在刚刚我抢的票:2025年1月8日 上午9.00多 抢到了哈哈哈哈— 其实还是有用的我是在 8:59:56运行程序的

在这里插入图片描述
在这里插入图片描述

上一篇帖子,我们已经了解了如何用python自动登录12306实现自动抢票,现在我们来一个进阶的版本,实现cookie免登录,这样可绕过验证码实现自动抢票。同时包括环境如何配置,也在这个帖子里面。

上一篇帖子的链接:https://blog.csdn.net/xaing1314/article/details/144868504

配置selenium自动化的帖子链接:https://blog.csdn.net/xaing1314/article/details/144869489?spm=1001.2014.3001.5502

需求:上此的帖子,需要自动登录,并且需要手机验证码,在真实抢票中太过繁琐,所有我自己也在思索,找了帖子和B站,终于实现了用cookie技术自动免登录12306。在今天上午9.00 (2025-01-07)抢票(2025-01-21)成功。

如何使用:1.比如9.00正式抢票,可以在8.53左右二维码扫描登录,当然是要配合下方程序,这样9.00可以正式抢票无需登录,cookie也不会失效。2.直接在8.59.58左右运行此程序,即可。

今日实战:今天运行其实是抢到了,但是他一直在等待,也就是页面一直停在哪里,其实那个时候你可以用手点击操作,因为我们是进来了,不需要去管程序的对错。也就是说,程序帮你操作到哪一步,如果卡住了,直接上手。这也让我有想做一个多线程的想法,将多线程加入这个程序中。

在这里插入图片描述

提示:以下是本篇文章正文内容,下面案例可供参考

一、cookie免登录

1.cookie的讲解: Cookie也被称为小型文本文件,是由服务器发送到用户浏览器并保存在用户计算机或移动设备上的一种数据形式。以下是对Cookie的详细解释:

定义与工作原理定义:Cookie是网站在用户浏览器中创建和存储的小型文本文件,用于辨别用户身份和存储用户相关信息。工作原理:当用户访问某个网站时,服务器会在用户的浏览器中创建一个Cookie,并将其存储在用户的计算机或移动设备上。当用户再次访问该网站时,浏览器会将Cookie发送回服务器,服务器通过读取Cookie中的信息来识别用户身份或获取用户的个性化设置。

2.获取cookie的代码如下: 程序运行后会打开登录界面,然后使用的二维码登录。这样程序可以得到当前的cookie值字段,在cookie失效前无须再进行登录。

<0001>初始化浏览器的函数— browser_initial():

def browser_initial():
    """"
    进行浏览器初始化
    """
    # os.chdir('E:\\pythonwork')

    # 1.将加载项配置到启动浏览器中 打开/创建浏览器对象
    browser = webdriver.Chrome(service=Service(path))
    # 2.网址 https://kyfw.12306.cn/otn/resources/login.html -- 登录界面
    # https://kyfw.12306.cn/otn/leftTicket/init 选票界面可以 判断是否登录
    log_url = 'https://kyfw.12306.cn/otn/resources/login.html'
    return log_url, browser

<0002> 获得cookie的函数— get_cookies(browser):

def get_cookies(browser):
    """
    获取cookies保存至本地
    """
    browser.get(log_url)
    time.sleep(15)  # 进行扫码
    # selenium_login(browser)
    # print("登录成功")
    dictCookies = browser.get_cookies()  # 获取list的cookies
    string_Cookies = json.dumps(dictCookies)  # 转换成字符串保存
    with open('string_cookies.json', 'w') as f:
        f.write(string_Cookies)
    print('cookies保存成功!')

if __name__ == "__main__":
    log_url, browser = browser_initial()
    browser.get(log_url)
    # 1.二维码登录 保存 -- cookie -- 用完关掉
    get_cookies(browser)

运行后就会变成这样,找到二维码,让手机自动登录。
在这里插入图片描述
用手机扫描即可,这个操作是设置了时间time.sleep(15),你也可以在get_cookies(browser)中修改此代码,只有自己扫了登录成功,后续出现的cookie保存成功,才是最新的cookie值。

在这里插入图片描述

二、cookie登录函数与自动化 – 可以实现cookie值的匹配–实现自动登录 – 无须手机验证码

1.login_cookie函数代码

代码如下(示例):

def login_cookie(log_url, browser):
    """
    从本地读取cookies并刷新页面,成为已登录状态
    """
    # browser.get(log_url)
    with open('string_cookies.json', 'r', encoding='utf8') as f:
        listCookies = json.loads(f.read())

    # 往browser里添加cookies
    for cookie in listCookies:
        browser.add_cookie(cookie)
   
    time.sleep(1)
    # 如果是已登录的界面,免登录应该打开这个界面 https://kyfw.12306.cn/otn/view/index.html
    # https://www.12306.cn/index/ --12306官网首页
    browser.get(log_url)
    return browser

2.selenium_run(driver)函数代码 – 这里是可以到预定,然后抢票成功要10分钟之内自己付款。

def selenium_run(driver):

    # 11.1 选择出发的城市--点击那个框
    driver.find_element(by="css selector", value="#fromStationText").click()
    # 11.2 选择出发的城市--选择城市
    driver.find_element(by="css selector", value="#fromStationText").send_keys(login["from_city"])
    # 11.3 选择出发的城市--回车确定
    driver.find_element(by="css selector", value="#fromStationText").send_keys(Keys.ENTER)

    # 12.1 选择目的的城市--点击那个框
    driver.find_element(by="css selector", value="#toStationText").click()
    # 12.2 选择目的的城市--选择城市
    driver.find_element(by="css selector", value="#toStationText").send_keys(login['to_city'])
    # 12.3 选择目的的城市--回车确定
    driver.find_element(by="css selector", value="#toStationText").send_keys(Keys.ENTER)

    # 13.1 选择出发的日期--点击那个框
    driver.find_element(by="css selector", value="#train_date").clear()
    # 12.2 选择出发的日期--选择城市
    driver.find_element(by="css selector", value="#train_date").send_keys(login['train_date'])
    # 12.3 选择出发的日期--回车确定
    driver.find_element(by="css selector", value="#train_date").send_keys(Keys.ENTER)
    # # 12.4 点击--显示全部可预订的车次
    # driver.find_element(by="css selector", value="avail_ticket").click()
    # 12.5 点击查询
    driver.implicitly_wait(5)
    driver.find_element(by="css selector", value="#query_ticket").click()
    # num = int(input('请输入您想要的车次:'))
    # 点击预订按钮 -- 选择要预定的是第几躺车 -- 这个代码没有问题
    # driver.find_element(by="css selector", value='#ticket_65000G279007_01_03 > td.no-br').click()

    # //div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]/@id -- 但是selenium的find_elements不可以用@id找到元素。
    ticket_list = driver.find_elements(by="xpath", value='//div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]')
    ticket_num = ticket_list[login['num']].get_attribute("id")
    ticket_pre = ticket_num + ' > td.no-br'
    # 12.6 点击想要车次的预定按钮
    driver.find_element(by="css selector", value=f"#{ticket_pre}").click()

    # 13.1 勾选想要的乘车人
    driver.find_element(by="css selector", value='#normalPassenger_0').click()

    # 13.2 提交订单
    driver.find_element(by="css selector", value='#submitOrder_id').click()
    driver.implicitly_wait(5)
    # 13.3 选择靠窗的1F的位置 #erdeng1 > ul:nth-child(4) > li:nth-child(2) 是在浏览器右键copy selector选择出来的
    # # 1F是不可以选中的
    driver.find_element(by="css selector", value='#erdeng1 > ul:nth-child(4) > li:nth-child(2)').click()
    # 13.4 再次确认提交
    time.sleep(1)
    # 如果此处没有响应多点击就好 -- 加上 "try -- except"
    driver.find_element(by="css selector", value='#qr_submit_id').click()
    # driver.find_element(by="css selector", value='#qr_submit_id').click()
    # driver.find_element(by="css selector", value='#qr_submit_id').click()

三、完整的代码

1.代码主体 – 先运行get_cookies(browser),注释掉后面的两句代码,二维码登录以后,再注释掉get_cookies(browser),运行后面两个即可。

if __name__ == "__main__":
    log_url, browser = browser_initial()
    browser.get(log_url)
    # 1.二维码登录 保存 -- cookie -- 用完关掉
    get_cookies(browser)
    # 2.自动登录
    driver = login_cookie(log_url, browser)
    selenium_run(driver)


2.完整代码

import time
import json
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
path = r'D:\game\chromedriver.exe'


def browser_initial():
    """"
    进行浏览器初始化
    """
    # os.chdir('E:\\pythonwork')

    # 1.将加载项配置到启动浏览器中 打开/创建浏览器对象
    browser = webdriver.Chrome(service=Service(path))
    # 2.网址 https://kyfw.12306.cn/otn/resources/login.html -- 登录界面
    # https://kyfw.12306.cn/otn/leftTicket/init 选票界面可以 判断是否登录
    log_url = 'https://kyfw.12306.cn/otn/leftTicket/init'
    return log_url, browser


def get_cookies(browser):
    """
    获取cookies保存至本地
    """
    browser.get(log_url)
    time.sleep(15)  # 进行扫码
    # selenium_login(browser)
    # print("登录成功")
    dictCookies = browser.get_cookies()  # 获取list的cookies
    string_Cookies = json.dumps(dictCookies)  # 转换成字符串保存
    with open('string_cookies.json', 'w') as f:
        f.write(string_Cookies)
    print('cookies保存成功!')

def login_cookie(log_url, browser):
    """
    从本地读取cookies并刷新页面,成为已登录状态
    """
    # 这个是12306的登录界面 https://kyfw.12306.cn/otn/resources/login.html
    # browser.get(log_url)
    with open('string_cookies.json', 'r', encoding='utf8') as f:
        listCookies = json.loads(f.read())

    # 往browser里添加cookies
    for cookie in listCookies:
        # cookie_dict = {
        #     'domain': cookie.get('domain'),
        #     # "expires": cookie.get('value'),
        #     'httpOnly': cookie.get('httpOnly'),
        #     'name': cookie.get('name'),
        #     'path': cookie.get('path'),
        #     "sameSite": "Lax",
        #     'Secure': cookie.get('Secure'),
        #     'value': cookie.get('value'),
        # }
        browser.add_cookie(cookie)
    # browser.refresh()
    time.sleep(1)
    # 如果是已登录的界面,可以免登录直接进 https://kyfw.12306.cn/otn/view/index.html
    # https://www.12306.cn/index/ --12306官网首页
    browser.get(log_url)
    return browser

def selenium_run(driver):

    # 11.1 选择出发的城市--点击那个框
    driver.find_element(by="css selector", value="#fromStationText").click()
    # 11.2 选择出发的城市--选择城市
    driver.find_element(by="css selector", value="#fromStationText").send_keys(login["from_city"])
    # 11.3 选择出发的城市--回车确定
    driver.find_element(by="css selector", value="#fromStationText").send_keys(Keys.ENTER)

    # 12.1 选择目的的城市--点击那个框
    driver.find_element(by="css selector", value="#toStationText").click()
    # 12.2 选择目的的城市--选择城市
    driver.find_element(by="css selector", value="#toStationText").send_keys(login['to_city'])
    # 12.3 选择目的的城市--回车确定
    driver.find_element(by="css selector", value="#toStationText").send_keys(Keys.ENTER)

    # 13.1 选择出发的日期--点击那个框
    driver.find_element(by="css selector", value="#train_date").clear()
    # 12.2 选择出发的日期--选择城市
    driver.find_element(by="css selector", value="#train_date").send_keys(login['train_date'])
    # 12.3 选择出发的日期--回车确定
    driver.find_element(by="css selector", value="#train_date").send_keys(Keys.ENTER)
    # # 12.4 点击--显示全部可预订的车次
    # driver.find_element(by="css selector", value="avail_ticket").click()
    # 12.5 点击查询
    driver.implicitly_wait(5)
    driver.find_element(by="css selector", value="#query_ticket").click()
    # num = int(input('请输入您想要的车次:'))
    # 点击预订按钮 -- 选择要预定的是第几躺车 -- 这个代码没有问题
    # driver.find_element(by="css selector", value='#ticket_65000G279007_01_03 > td.no-br').click()

    # //div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]/@id -- 但是selenium的find_elements不可以用@id找到元素。
    ticket_list = driver.find_elements(by="xpath", value='//div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]')
    ticket_num = ticket_list[login['num']].get_attribute("id")
    ticket_pre = ticket_num + ' > td.no-br'
    # 12.6 点击想要车次的预定按钮
    driver.find_element(by="css selector", value=f"#{ticket_pre}").click()

    # 13.1 勾选想要的乘车人
    driver.find_element(by="css selector", value='#normalPassenger_0').click()

    # 13.2 提交订单
    driver.find_element(by="css selector", value='#submitOrder_id').click()
    driver.implicitly_wait(5)
    # 13.3 选择靠窗的1F的位置 #erdeng1 > ul:nth-child(4) > li:nth-child(2) 是在浏览器右键copy selector选择出来的
    # # 1F是不可以选中的
    driver.find_element(by="css selector", value='#erdeng1 > ul:nth-child(4) > li:nth-child(2)').click()
    # 13.4 再次确认提交
    time.sleep(1)
    # 如果此处没有响应多点击就好 -- 加上 "try -- except"
    # driver.find_element(by="css selector", value='#qr_submit_id').click()
    # driver.find_element(by="css selector", value='#qr_submit_id').click()
    # driver.find_element(by="css selector", value='#qr_submit_id').click()



f = open('login.json', encoding='utf-8').read()
login = json.loads(f)

if __name__ == "__main__":
    log_url, browser = browser_initial()
    browser.get(log_url)
    # 1.二维码登录 保存 -- cookie -- 用完关掉
    # get_cookies(browser)
    # 计算程序运行时间
    # start = time.perf_counter()
    # 2.自动登录

    driver = login_cookie(log_url, browser)
    # # 如果没有登录那就自动登录 -- 然后获得cookie自动保存
    # # if browser.find_element(by="css selector", value="#login_user").text == "登录":
    # # 3.自动买票
    selenium_run(driver)
    # end = time.perf_counter()
    # runTime = end - start
    # runTime_ms = runTime * 1000
    # # 输出运行时间
    # print("运行时间:", runTime, "秒")
    # print("运行时间:", runTime_ms, "毫秒")

3.login.json – 解释这个文件

在这里插入图片描述

图中字典信息:代表的是地址日期,num代表的是第几躺车,id_card身份证,后4位。这里面有用账户密码登录的信息,虽然这里用不上,但是我们上一个帖子是用这个的,所以我把它写在了一起。

四、总结

1.几个注意:代码中的url最好是用登录成功的页面,而非登录页面。不然会一直显示要登录。


log_url = 'https://kyfw.12306.cn/otn/resources/login.html'
log_url = 'https://kyfw.12306.cn/otn/leftTicket/init'  ##---用这个

2.改进:今天真正的实战我也挺满意的就是想着再改进一下,看看多线程是否可以直接抢到。明天就要真正抢票啦 – 给大家看看今天的战果。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2273513.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习驱动的蛋白质设计技术与实践

通过设计特定的蛋白质结构&#xff0c;可以实现预期的生物功能&#xff0c;如催化特定化学反应、识别和结合特定分子、调控生物信号传导等&#xff0c;为生物医学、药物研发、生物技术等领域提供重要工具和解决方案。传统的蛋白质设计方法主要依赖于已知蛋白质结构的同源建模、…

【动态重建】时间高斯分层的长体积视频

标题&#xff1a;Representing Long Volumetric Video with Temporal Gaussian Hierarchy 来源&#xff1a;浙江大学 链接&#xff1a;https://zju3dv.github.io/longvolcap/ 文章目录 摘要一、前言二、主要方法2.1 时间高斯分层2.2 高效渲染2.3 层次结构更新2.4 紧凑的外观模型…

【STM32+CubeMX】 新建一个工程(STM32F407)

相关文章&#xff1a; 【HAL库】 STM32CubeMX 教程 1 --- 下载、安装 目录 第一部分、新建工程 第二部分、工程文件解释 第三部分、编译验证工程 友情约定&#xff1a;本系列的前五篇&#xff0c;为了方便新手玩家熟悉CubeMX、Keil的使用&#xff0c;会详细地截图每一步Cu…

el-date-picker 不响应change事件的解决办法

前言 接到需要把element plus组件的日期时间选择器的input输入框展示隐藏&#xff0c;遇到点击确认按钮change事件不被触发问题&#xff0c;解决办法如下&#xff1a; ①visible-change的回调参考 即根据visible-change的方法里的回调参数进行需要操作 const visibleChange …

api开发如何在代码中使用京东商品详情接口的参数?

选择编程语言和相关工具 以 Python 为例&#xff0c;你可以使用requests库来发送 HTTP 请求获取接口数据。如果是 Java&#xff0c;可以使用OkHttp等库。 Python 示例 假设你已经安装了requests库&#xff0c;以下是一个简单的代码示例来获取和使用京东商品详情接口参数&#…

【docker系列】可视化Docker 管理工具——Portainer

1. 介绍 Portainer是一个可视化的Docker操作界面&#xff0c;提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作&#xff08;包括上传下载镜像&#xff0c;创建容器等操作&#xff09;、事件日志显示、容器控制台操作、Swarm集群和服务等集中管理和操作、登录…

机器学习基础-大语言模型

目录 大语言模型的基本概念 “大”体现在什么地方&#xff1f; 预训练微调两阶段的基本流程和作用 第一阶段&#xff1a;利用语言模型进行无监督预训练 第二阶段&#xff1a;通过监督微调的模式解决下游任务 BERT模型中MLM和NSP机制基本概念 MLM NSP Prompt学习的基本概…

Ubuntu挂载Windows 磁盘,双系统

首先我们需要在终端输入这个命令&#xff0c;来查看磁盘分配情况 lsblk -f 找到需要挂载的磁盘&#xff0c;检查其类型&#xff08; 我的/dev/nvme2n1p1类型是ntfs&#xff0c;名字叫3500winData&#xff09; 然后新建一个挂载磁盘的目录&#xff0c;我的是/media/zeqi/3500wi…

Java设计模式 —— 【行为型模式】命令模式(Command Pattern) 详解

文章目录 模式介绍优缺点适用场景结构案例实现注意事项 模式介绍 有时候需要向某些对象发送请求&#xff0c;但是并不知道请求的接收者是谁&#xff0c;也不知道被请求的操作是什么。此时希望用一种松耦合的方式来设计程序&#xff0c;使得请求发送者和请求接收者能够消除彼此…

如何很快将文件转换成另外一种编码格式?编码?按指定编码格式编译?如何检测文件编码格式?Java .class文件编码和JVM运行期内存编码?

如何很快将文件转换成另外一种编码格式? 利用VS Code右下角的"选择编码"功能&#xff0c;选择"通过编码保存"可以很方便将文件转换成另外一种编码格式。尤其&#xff0c;在测试w/ BOM或w/o BOM, 或者ANSI编码和UTF编码转换&#xff0c;特别方便。VS文件另…

AnaConda下载PyTorch慢的解决办法

使用Conda下载比较慢&#xff0c;改为pip下载 复制下载链接到迅雷下载 激活虚拟环境&#xff0c;安装whl&#xff0c;即可安装成功 pip install D:\openai.wiki\ChatGLM2-6B\torch-2.4.1cu121-cp38-cp38-win_amd64.whl

opencv摄像头标定程序实现

摄像头标定是计算机视觉中的一个重要步骤&#xff0c;用于确定摄像头的内参&#xff08;如焦距、主点、畸变系数等&#xff09;和外参&#xff08;如旋转矩阵和平移向量&#xff09;。OpenCV 提供了方便的工具来进行摄像头标定。下面分别给出 C 和 Python 的实现。 1. C 实现…

UE5AI感知组件

官方解释&#xff1a; AI感知系统为Pawn提供了一种从环境中接收数据的方式&#xff0c;例如噪音的来源、AI是否遭到破坏、或AI是否看到了什么。 AI感知组件&#xff08;AIPerception Component&#xff09;是用于实现游戏中的非玩家角色&#xff08;NPC&#xff09;对环境和其…

Python生日祝福烟花

1. 实现效果 2. 素材加载 2个图片和3个音频 shoot_image pygame.image.load(shoot(已去底).jpg) # 加载拼接的发射图像 flower_image pygame.image.load(flower.jpg) # 加载拼接的烟花图 烟花不好去底 # 调整图像的像素为原图的1/2 因为图像相对于界面来说有些大 shoo…

智能手机租赁系统全新模式改变消费习惯与商家盈利路径

内容概要 智能手机租赁系统的崛起&#xff0c;让我们瞄到了一个消费市场的新风向标。想象一下&#xff0c;传统上人们总是为了最新款手机奋不顾身地排队、借钱甚至是透支信用卡。现在&#xff0c;通过灵活的租赁选项&#xff0c;消费者可以更加随意地体验高科技产品&#xff0…

【简博士统计学习方法】第1章:3. 统计学习方法的三要素

3. 统计学习方法的三要素 3.1 监督学习的三要素 3.1.1 模型 假设空间&#xff08;Hypothesis Space&#xff09;&#xff1a;所有可能的条件概率分布或决策函数&#xff0c;用 F \mathcal{F} F表示。 若定义为决策函数的集合&#xff1a; F { f ∣ Y f ( X ) } \mathcal{F…

牛客网刷题 ——C语言初阶(2分支和循环-for)——打印菱形

1. 题目描述 用C语言在屏幕上输出以下图案&#xff1a; 2. 思路 我是先上手&#xff0c;先把上半部分打印出来&#xff0c;然后慢慢再来分析&#xff0c;下面这是我先把整个上半部分打印出来&#xff0c;因为空格不方便看是几个&#xff0c;这里先用&代替空格了 然后这里…

STM32——系统滴答定时器(SysTick寄存器详解)

文章目录 1.SysTick简介2.工作原理3.SysTick寄存器4.代码延时逻辑5.附上整体代码6.一些重要解释 1.SysTick简介 Cortex-M处理器内集成了一个小型的名为SysTick(系统节拍)的定时器,它属于NVIC的一部分,且可以产生 SysTick异常(异常类型#15)。SysTick为简单的向下计数的24位计数…

《Opencv》信用卡信息识别项目

目录 一、项目介绍 二、数据材料介绍 1、模板图片&#xff08;1张&#xff09; 2、需要处理的信用卡图片&#xff08;5张&#xff09; 三、实现过程 1、导入需要用到的库 2、设置命令行参数 3、模板图像中数字的定位处理 4、信用卡图像处理 5、模板匹配 四、总结 一…

密码学科普

1 信息传输中的安全隐患 1. 窃听 解决方案&#xff1a;明文加密&#xff0c;X只能窃听到密文 2. 假冒 解决方案&#xff1a;消息认证码或者数字签名 3. 篡改 解决方案&#xff1a;消息认证码或者数字签名 4. 事后否认 解决方案&#xff1a;数字签名 2 对称加密/非对称加密 1…