上一篇写了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,一边查一边写,应该有很多不规范和漏洞,欢迎指正

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

  1. Python+Selenium实现新浪微博自动登录

    Python+Selenium实现新浪微博自动登录 环境说明:win10+eclipse+chrome 备注:需要下载chrome浏览器的驱动(地址: https://sites.google.com ...

  2. Python+Selenium实现12306模拟登录

    最近在学python爬虫,学习到了selenium的使用,看网上有很多使用selenium模拟登录12306网站的文章,于是自己也尝试了一下.期间遇到了一些问题,也参考了很多大佬的文章最终得到了解决, ...

  3. Python+selenium+chromedriver实现自动登录微博并发微博

    python环境这里就是默认安好的状态 首先要确保安装了selenium 在cmd/终端界面输入 pip install selenium 如果是pycharm的话那就是 Pycharm->Pr ...

  4. Python selenium实现微博自动登录

    (一)编程环境 操作系统:Win 10 编程语言:Python 3.6 (二)安装selenium 这里使用selenium实现. 如果没有安装过python的selenium库,则安装命令如下 pi ...

  5. python+selenium+chrome实现自动登录百度

    #python3.4+selenium3.5+chrome版本 63.0.3239.132+chrome驱动chromedriver.exe #实现自动登录百度 from selenium impor ...

  6. python+selenium实现12306抢票

    python+selenium实现12306抢票 一.准备工作 1.要先下载相关的包,selenium.interval.最好使用国内清华源 pip install (which package) - ...

  7. Python零基础之自动登录12306

    Python零基础之自动登录12306 文章目录 Python零基础之自动登录12306 需要注意的问题 直接上代码 分析过程在代码注释中已经写的较为清楚 功能实现是代码运行后打开生成的code2图片 ...

  8. java + Selenium实现12306自动购票

    为什么搞这个东西?[java + Selenium实现12306自动购票, 余票监测] 1.主要是12306是爬虫界的一个分水岭,所以我一直想玩12306[本次的实现并非真正意义上的破解12306实现 ...

  9. 爬虫学习笔记(十八)—— 点触验证码:超级鹰、12306自动登录

    一.打码平台 点触验证码是一种常见的反爬手段. 解决方案有两种:一种是直接解决,这需要深度学习机器学习等图像处理技术,以大量的数据训练识别模型,最终达到模型足矣识别图片中的文字提示和应该点击的区域之间 ...

最新文章

  1. 什么限制了GNN的能力?首篇探究GNN普适性与局限性的论文出炉!
  2. DBA工具——DMV——通过sys.dm_exec_procedure_stats查看存储过程执行信息
  3. RPC实现Consumer 远程调用
  4. java获取u盘_实例分享java监听u盘的方法
  5. PLSQL Developer 安装与配置
  6. qt5变成内部头文件 ubuntu_Ubuntu下Visual Studio Code软件的安装和使用
  7. python all和any用法_python any()和all()用法
  8. 笨办法学 Linux 引言
  9. 完全使用CSS制作下拉菜单
  10. python自动化测试-Python自动化测试如何自动生成测试用例?
  11. 化学能推进永远无法实现外星旅行
  12. Android PDF 的 读取 与 生成
  13. python人脸检测与微信小程序_微信小程序人脸识别功能
  14. Linux操作系统加固
  15. 转载ios开发如何使用Xcode的Targets来管理开发和生产版本的构建
  16. 制作一份高质量的APP运营推广方案
  17. 【MySQL面试】MyISAM和InnoDB的不同
  18. AI记者上岗,百度数字人度晓晓云上采访全国五一劳动奖获得者
  19. 微信24小时到账_千万别被微信给骗了,二十四小时到账根本不能撤回!
  20. 计算机为什么有网络凭证,Win10访问局域网中计算机共享文件显示需要网络凭证怎么办?...

热门文章

  1. 军队文职(数学2+物理)——考试介绍
  2. 如何使用ChatGPT版本的Bing搜索引擎?
  3. FindElement和FindElements命令
  4. mysql复数记录,MySQL 数据库铁律(小结)
  5. php libiconv close_PHP 編譯安裝時出現 undefined reference to `libiconv' 錯誤的解決方法
  6. 给docker配置个人账号的阿里云镜像加速器以及docker底层原理
  7. 从马帮到金蝶云星空通过接口配置打通数据
  8. Python以及Pycharm安装、汉化详细教程
  9. 【转载】Java Instrument 功能使用及原理
  10. Android开发示例代码