python+selenium实现12306自动登录刷票抢票(自己做黄牛?!)

article/2025/8/19 20:20:55

上一篇写了12306的自动登录破解验证图https://blog.csdn.net/weixin_38283159/article/details/86498159
这篇算是它的后续部分加上了简单的刷票和预订功能,毕竟登录一下没什么实际价值嘛
博主曾被黄牛挣过一百大洋至今还耿耿于怀,不清楚他们到达是如何抢票的,我能想到的简单方案就是不断的刷新判断了…
效果图(自动登录部分gif见上篇)
在这里插入图片描述
思路就是用selenium模拟我们买票的流程,所以就不详细说了
代码
说明:代码只处理了二等座(一等座也适用,EF位置不能选),和无需选位置的(关于硬卧等类型是否能够选上下铺我也不知道)

#coding:u8from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
import requests
import base64
import re
import time
import osclass Demo():def __init__(self,user_name="531218020@qq.com",pass_word="***********"):self.coordinate=[[-105,-20],[-35,-20],[40,-20],[110,-20],[-105,50],[-35,50],[40,50],[110,50]]self.position=["A","B","C","D","E","F"]self.type=["一等座","二等座","硬座","硬卧","软卧","商务座"]self.type_code=["M","0","1","3","4","9"]self.user_name=user_nameself.pass_word=pass_wordwith open("code.json", 'r') as file:code=eval(file.read())self.from_station=code[input("From station:")]self.to_station=code[input("To station:")]self.train_date=input("出发时间(年-月-日):")self.is_student=bool(input("Is student(0/1):"))login_url="https://kyfw.12306.cn/otn/resources/login.html"driver = webdriver.Chrome()driver.set_window_size(1200, 900)driver.get(login_url)self.driver=driverif not os.path.exists("verify"):os.mkdir("verify")if os.path.exists("verify.jpg"):name=os.path.join("verify",str(len(os.listdir("verify")))+".jpg")os.rename("verify.jpg",name)			def login(self):		account=self.driver.find_element_by_class_name("login-hd-account")account.click()userName=self.driver.find_element_by_id("J-userName")userName.send_keys(self.user_name)password=self.driver.find_element_by_id("J-password")password.send_keys(self.pass_word)		def getVerifyImage(self):try:			img_element =WebDriverWait(self.driver, 100).until(EC.presence_of_element_located((By.ID, "J-loginImg")))except Exception as e:print(u"网络开小差,请稍后尝试")	base64_str=img_element.get_attribute("src").split(",")[-1]imgdata=base64.b64decode(base64_str)with open('verify.jpg','wb') as file:file.write(imgdata)self.img_element=img_elementdef getVerifyResult(self):url="http://littlebigluo.qicp.net:47720/"response=requests.request("POST",url,data={"type":"1"},files=files={'pic_xxfile':open('verify.jpg','rb')})result=[]#print(response.text)try:for i in re.findall("<B>(.*)</B>",response.text)[0].split(" "):result.append(int(i)-1)except Exception as e:print(u"图像处理服务器繁忙,请稍后尝试")self.result=resultdef moveAndClick(self):try:self.Action=ActionChains(self.driver)for i in self.result:self.Action.move_to_element(self.img_element).move_by_offset(self.coordinate[i][0],self.coordinate[i][1]).click()self.Action.perform()except Exception as e:print(e.message())def submit(self):self.driver.find_element_by_id("J-login").click()def queryTicket(self):query_url="https://kyfw.12306.cn/otn/leftTicket/init"self.driver.get(query_url)self.driver.execute_script("document.getElementById('fromStation').removeAttribute('type')")fromStation=self.driver.find_element_by_id("fromStation")fromStation.send_keys(self.from_station)self.driver.execute_script("document.getElementById('toStation').removeAttribute('type')")toStation=self.driver.find_element_by_id("toStation")toStation.send_keys(self.to_station)self.driver.execute_script("document.getElementById('train_date').removeAttribute('readonly')")trainDate=self.driver.find_element_by_id("train_date")trainDate.clear()trainDate.send_keys(self.train_date)if self.is_student:self.driver.find_element_by_id("sf2").click()self.driver.find_element_by_id("query_ticket").click()def ticketOrder(self):trains=self.driver.find_elements_by_class_name("number")for i,item in enumerate(trains):print("【{}】{}".format(i,item.text))num=input("请输入预定车次编号:")self.driver.find_elements_by_class_name("btn72")[int(num)].click()		ul=WebDriverWait(self.driver, 100).until(EC.presence_of_element_located((By.ID, "normal_passenger_id")))time.sleep(1)lis=ul.find_elements_by_tag_name("li")for i,item in enumerate(lis):print("【{}】{}".format(i,item.find_elements_by_tag_name("label")[0].text))num=input("请输入购票人编号:")buy_num=int(num)lis[int(num)].find_elements_by_tag_name('input')[0].click()if self.is_student:self.driver.find_element_by_id("dialog_xsertcj_ok").click()else:self.driver.find_element_by_id("dialog_xsertcj_cancel").click()seatType=self.driver.find_element_by_id("seatType_1")for i,item in enumerate(self.type):print("【{}】{}".format(i,item))num=input("请输入座位类型:")code=self.type_code[int(num)]print("=======余票查询=======")count=1flag=Falsewhile 1:print("第{}次查询".format(count))		count+=1for i,item in enumerate(seatType.find_elements_by_tag_name("option")):if item.get_attribute("value") is code:flag=Trueitem.click()break;if flag:break;self.driver.back()time.sleep(1)self.driver.forward()#================================================ul=WebDriverWait(self.driver, 100).until(EC.presence_of_element_located((By.ID, "normal_passenger_id")))time.sleep(1.5)lis=ul.find_elements_by_tag_name("li")lis[buy_num].find_elements_by_tag_name('input')[0].click()if self.is_student:self.driver.find_element_by_id("dialog_xsertcj_ok").click()else:self.driver.find_element_by_id("dialog_xsertcj_cancel").click()seatType=self.driver.find_element_by_id("seatType_1")#================================================self.driver.find_element_by_id("submitOrder_id").click()if code is "M" or code is"0": num=input("请输入座位编号:")for i,item in enumerate(self.position):print("【{}】{}".format(i,item))num=input("请输入座位编号:")id="1"+self.position[int(num)]self.driver.find_element_by_id(id).click()time.sleep(1)isorder=input("已有余票,是否预订(【0】取消 【1】预定):")if int(isorder):self.driver.find_element_by_id("qr_submit_id").click()print("预定成功,请及时付款")else:print("Bye~")def __call__(self):self.login()time.sleep(2)self.getVerifyImage()time.sleep(1)self.getVerifyResult()time.sleep(1)self.moveAndClick()time.sleep(1)self.submit()time.sleep(10)self.queryTicket()time.sleep(2)self.ticketOrder()time.sleep(10000)
Demo()()

两点说明
1、代码中使用的code.json外部文件获取见https://blog.csdn.net/weixin_38283159/article/details/86490978
中的trainService.pycrawlCodeMess方法
2、如果登录图片验证失败,在十秒内可以手动点击验证图让程序继续下去

写在最后
刚接触selenium,一边查一边写,应该有很多不规范和漏洞,欢迎指正


http://chatgpt.dhexx.cn/article/dKucFiwL.shtml

相关文章

转载--12306刷票记

转载自&#xff1a;http://www.360doc.com/content/13/0122/17/453497_261790962.shtml 我也记不清啥时候动了写bot刷票这个念头的。原因很简单&#xff0c;我一直认为作为一个以代码谋生的不合格程序员&#xff0c;只有把生产工具用好&#xff0c;才能增加自己存在的价值。 首…

12306自动刷票下单-查票下单(二)

前言 上篇写了12306登录&#xff0c;隔了快一个月了&#xff0c;才准备动手写下单篇&#xff0c;真的要非常感谢博客园的 Asimple朋友&#xff0c;如果不是看到你的留言&#xff0c;我几乎都忘了要写下篇了&#xff0c;这一点在简书上就不好&#xff0c;都没人看/(ㄒoㄒ)/~~&a…

快过年了,Python实现12306查票以及自动购票....

马上就要过年了&#xff0c;听说还有人买不到票&#xff1f; 不要慌&#xff0c;今天咱们来用Python做一个自动查票抢票的脚本&#xff0c;24小时抢票&#xff0c;谁抢的过你&#xff01; python实现12306自动抢票查票 准备工作爬虫思路 准备工作 环境 Python 3.8Pycharm 插…

12306智能刷票,订票

乐在分享 python版本支持 2.7.10 - 2.7.15 依赖库 依赖若快 若快注册地址&#xff1a;http://www.ruokuai.com/client/index?6726 推荐用若快&#xff0c;打码兔平台已经关闭项目依赖包 requirements.txt安装方法 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r…

12306自动刷票下单-下单

12306自动刷票下单-登录 12306自动刷票下单-查票预定 下单 进入下单界面了 https://kyfw.12306.cn/otn/confirmPassenger/initDc 还有一个请求https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs 仔细看一下返回值&#xff0c;是我们常用联系人的信息&…

12306自动刷票下单-下单(三)

12306自动刷票下单-登录篇&#xff08;一&#xff09;12306自动刷票下单-查票预定&#xff08;二&#xff09; 下单 进入下单界面了 https://kyfw.12306.cn/otn/confirmPassenger/initDc 还有一个请求https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs 仔细看一下…

新手写的一个12306刷票工具

本来是去年打算写的一个12306的刷票工具&#xff0c;但是一直拖着没完成。过完年才搞好。其实也不算写好&#xff0c;只是感觉都过完年了这个东西都没多大意义&#xff0c;在说各大网站上都有这个功能。但就当记录一下吧。 刚开始写的时候困扰我的其实不是买票的流程&#xff0…

【使用教程】面向回家编程-12306智能刷票,订票

代码链接&#xff1a;https://github.com/testerSunshine/12306 实名感谢&#xff1a;testerSunshine 春运一票难求&#xff0c;很多朋友都听说了GitHub上的12306抢票神器&#xff0c;但苦于没有计算机编程基础或在使用过程中遇到暂时无法解决的问题导致抢票失败。特撰写本博…

12306自动刷票下单-登录篇(一)

12306网站推出图片验证码以后&#xff0c;对于抢票软件就提出了更高的要求&#xff0c;本篇并不涉及自动识别验证码登录&#xff08;主要是博主能力所限&#xff09;&#xff0c;提供一个途径-打码平台&#xff0c;这个几乎是可以破解所有验证码了&#xff0c;本篇主要是分享一…

12306刷票脚本

我也在刷票&#xff0c;不过发现12306还是发生了一些变化&#xff0c;在使用过程中&#xff0c;发现会自动退出登录。所以对脚本做了一些改动。顺便加了一些新的功能。具体如下&#xff1a; 防自动退出 添加刷到票后发起桌面通知 勾选某些类型的车 选择发站站点 …

c#模拟网页实现12306登陆、自动刷票、自动抢票完全篇

这一篇文章&#xff0c;我将从头到尾教大家使用c#模拟网页面登陆12306网站&#xff0c;自动刷票&#xff0c;选择订票人&#xff0c;到最后一步提交订单。研究过HTTP协议的童鞋们都知道&#xff0c;我们在访问网站时&#xff0c;是有两种方式的&#xff0c;POST和GET方式&#…

你距离家只差一个刷票脚本而已——12306刷票脚本升级版

马上就要回家了&#xff0c;票还没有。你是否用到了我去年发布的刷票脚本呢。传送门~ 我也在刷票&#xff0c;不过发现12306还是发生了一些变化&#xff0c;在使用过程中&#xff0c;发现会自动退出登录。所以对脚本做了一些改动。顺便加了一些新的功能。具体如下&#xff1a;…

搞技术的要不要学习财务知识

越是大型的集团或者企业&#xff0c;公司里面设立的部门就越多&#xff0c;也越细化&#xff0c;各部门之间既相互独立管理&#xff0c;又是相互的辅助支持&#xff0c;所以在工作中经常遇到这样的一个问题&#xff0c;就是做技术的要不要学习财务知识。这个问题其实就是把技术…

财务管理的一般常识

2019独角兽企业重金招聘Python工程师标准>>> 财务总监助理在协助财务总监做好企业理财规划与管理的时候需要首先了解以下的有关知识&#xff1a; —、财务和企业财务管理的概念 所谓“财务”&#xff0c;通俗地讲就是有关“钱财”的事务。从事一切事业都离不开钱财&…

财政系统基本知识

文章目录 一、基础数据1、单位管理修改2、部门信息 二、资产账1、卡片登记&#xff08;新增资产&#xff09;2、新增资产入账&#xff0c;也可批量入账3、卡片变动1&#xff09;普通信息变动 >>>普通信息确认2&#xff09;资产价值变动3&#xff09;资产大类变动4&…

身为企业管理者,必须了解的财务知识

财务管理工作是企业管理工作中的核心内容&#xff0c;也是企业管理工作中的难点内容&#xff0c;对于集团企业来讲更是任务艰巨而又问题频出。然而&#xff0c;信息时代的来临为解决和完善企业财务管理问题提供了新思路&#xff0c;就集团企业而言&#xff0c;财务管理信息化基…

业务:财务会计业务知识

一、引言 会计是以货币为主要计量单位&#xff0c;对企业、事业、机关、团体及其他经济组织的经济活动进行记录、计算、控制、分析、报告&#xff0c;以提供财务和管理信息的工作。会计的职能主要是反映和控制经济活动过程&#xff0c;保证会计信息的合法、真实、准确和完整&a…

软件测试分类

一、软件测试的分类 1、按开发阶段&#xff1a;单元测试、集成测试、系统测试、验收测试 2、按测试实施组织&#xff1a;α、β、第三方 3、按测试执行方式&#xff1a;静态测试、动态测试 4、按是否查看代码&#xff1a;黑盒测试、白盒测试、灰盒测试 5、按是否手工执行划分&a…

【软件工程】软件测试报告——软件测试说明书

【备注】本说明书由华中农业大学2018级计算机科学与技术专业的刘畅、刘铠铭、张清望、卢家伟四位同学共同完成。 文章目录 1 引言1.1 编写目的1.2 背景1.3 术语和缩略词1.4 参考资料 2 测试用例设计3 测试结果及分析3.1 测试环境3.2 测试用例执行3.3 结论及建议 1 引言 1.1 编…

软件测试模型有哪些?

目录 1、瀑布模型 2、V模型 3、W模型 4、H模型 5、X模型 6、前置测试模型 1、瀑布模型 瀑布模型&#xff08;Waterfall Model&#xff09;是一个软件生命周期模型&#xff0c;开发过程是通过设计一系列阶段顺序展开的&#xff0c;从系统需求分析开始直到产品发布和维护&…