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

python无需验证码免登录12306抢票 --selenium(2)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

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


前言

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

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

在这里插入图片描述


在这里插入图片描述

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

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

配置selenium自动化的帖子链接:https://blog.ZEEKLOG.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():

defbrowser_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):

defget_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)# 转换成字符串保存withopen('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)

运行后就会变成这样,找到二维码,让手机自动登录。

在这里插入图片描述

你也可以在get_cookies(browser)中修改此代码,只有自己扫了登录成功,后续出现的cookie保存成功,才是最新的cookie值。

在这里插入图片描述

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

1.login_cookie函数代码

代码如下(示例):

deflogin_cookie(log_url, browser):""" 从本地读取cookies并刷新页面,成为已登录状态 """# browser.get(log_url)withopen('string_cookies.json','r', encoding='utf8')as f: listCookies = json.loads(f.read())# 往browser里添加cookiesfor 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分钟之内自己付款。

defselenium_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'defbrowser_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 defget_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)# 转换成字符串保存withopen('string_cookies.json','w')as f: f.write(string_Cookies)print('cookies保存成功!')deflogin_cookie(log_url, browser):""" 从本地读取cookies并刷新页面,成为已登录状态 """# 这个是12306的登录界面 https://kyfw.12306.cn/otn/resources/login.html# browser.get(log_url)withopen('string_cookies.json','r', encoding='utf8')as f: listCookies = json.loads(f.read())# 往browser里添加cookiesfor 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 defselenium_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.改进:今天真正的实战我也挺满意的就是想着再改进一下,看看多线程是否可以直接抢到。明天就要真正抢票啦 – 给大家看看今天的战果。

在这里插入图片描述

Read more

【OpenClaw从入门到精通】第10篇:OpenClaw生产环境部署全攻略:性能优化+安全加固+监控运维(2026实测版)

【OpenClaw从入门到精通】第10篇:OpenClaw生产环境部署全攻略:性能优化+安全加固+监控运维(2026实测版)

摘要:本文聚焦OpenClaw从测试环境走向生产环境的核心痛点,围绕“性能优化、安全加固、监控运维”三大维度展开实操讲解。先明确生产环境硬件/系统选型标准,再通过硬件层资源管控、模型调度策略、缓存优化等手段提升响应速度(实测响应效率提升50%+);接着从网络、权限、数据三层构建安全防护体系,集成火山引擎安全方案拦截高危操作;最后落地TenacitOS可视化监控与Prometheus告警体系,配套完整故障排查清单和虚拟实战案例。全文所有配置、代码均经实测验证,兼顾新手入门实操性和进阶读者的生产级部署需求,帮助开发者真正实现OpenClaw从“能用”到“放心用”的跨越。 优质专栏欢迎订阅! 【DeepSeek深度应用】【Python高阶开发:AI自动化与数据工程实战】【YOLOv11工业级实战】 【机器视觉:C# + HALCON】【大模型微调实战:平民级微调技术全解】 【人工智能之深度学习】【AI 赋能:Python 人工智能应用实战】【数字孪生与仿真技术实战指南】 【AI工程化落地与YOLOv8/v9实战】【C#工业上位机高级应用:高并发通信+性能优化】 【Java生产级避坑指南:

By Ne0inhk
ARM Linux 驱动开发篇--- Linux 并发与竞争实验(互斥体实现 LED 设备互斥访问)--- Ubuntu20.04互斥体实验

ARM Linux 驱动开发篇--- Linux 并发与竞争实验(互斥体实现 LED 设备互斥访问)--- Ubuntu20.04互斥体实验

🎬 渡水无言:个人主页渡水无言 ❄专栏传送门: 《linux专栏》《嵌入式linux驱动开发》《linux系统移植专栏》 ❄专栏传送门: 《freertos专栏》《STM32 HAL库专栏》 ⭐️流水不争先,争的是滔滔不绝  📚博主简介:第二十届中国研究生电子设计竞赛全国二等奖 |国家奖学金 | 省级三好学生 | 省级优秀毕业生获得者 | ZEEKLOG新星杯TOP18 | 半导纵横专栏博主 | 211在读研究生 在这里主要分享自己学习的linux嵌入式领域知识;有分享错误或者不足的地方欢迎大佬指导,也欢迎各位大佬互相三连 目录 前言  一、实验基础说明 1.1、互斥体简介 1.2 本次实验设计思路 二、硬件原理分析(看过之前博客的可以忽略) 三、实验程序编写 3.1 互斥体 LED 驱动代码(mutex.c) 3.2.1、设备结构体定义(28-39

By Ne0inhk
Flutter for OpenHarmony:swagger_dart_code_generator 接口代码自动化生成的救星(OpenAPI/Swagger) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:swagger_dart_code_generator 接口代码自动化生成的救星(OpenAPI/Swagger) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 后端工程师扔给你一个 Swagger (OpenAPI) 文档地址,你会怎么做? 1. 对着文档,手写 Dart Model 类(容易写错字段类型)。 2. 手写 Retrofit/Dio 的 API 接口定义(容易拼错 URL)。 3. 当后端修改了字段名,你对着报错修半天。 这是重复劳动的地狱。 swagger_dart_code_generator 可以将 Swagger (JSON/YAML) 文件直接转换为高质量的 Dart 代码,包括: * Model 类:支持 json_serializable,带 fromJson/

By Ne0inhk
Linux 开发别再卡壳!makefile/git/gdb 全流程实操 + 作业解析,新手看完直接用----《Hello Linux!》(5)

Linux 开发别再卡壳!makefile/git/gdb 全流程实操 + 作业解析,新手看完直接用----《Hello Linux!》(5)

文章目录 * 前言 * make/makefile * 文件的三个时间 * Linux第一个小程序-进度条 * 回车和换行 * 缓冲区 * 程序的代码展示 * git指令 * 关于gitee * Linux调试器-gdb使用 * 作业部分 前言 做 Linux 开发时,你是不是也遇到过这些 “卡脖子” 时刻?写 makefile 时,明明语法没错却报错,最后发现是依赖方法行没加 Tab;想提交代码到 gitee,记不清 git add/commit/push 的 “三板斧”,还得反复搜教程;用 gdb 调试程序,输了命令没反应,才想起编译时没加-g生成 debug 版本;甚至连写个进度条,都搞不懂\r和\n的区别,导致进度条乱跳…… 其实这些问题,

By Ne0inhk