前段时间由于12306增加了候补功能,暴力去抢票意义不是很大,但在车票刚放出时前几分钟运行还是有些用处的,姑且就当成一个实验吧。

该程序需要刚开始去扫码登录,如果账号密码肯定需要验证码就比较麻烦了,所以一开始扫码登录,后续就交给程序跑就好了

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException,ElementNotVisibleException
import csv# 为什么需要把driver放在外面?
# 因为如果放在里面,那么driver将会随着对象的销毁而被销毁
# 而我们的TrainSpider的对象是放在main函数中执行的,
# 只要main函数运行完成后,里面所有的变量都不会被销毁,
# 也就说spider也会被销毁,那么spider里面的driver也会被销毁。
driver = webdriver.Chrome(executable_path="D:\ProgramApp\chromedriver\chromedriver73.exe")# 9:商务座,M:一等座,O:二等座,3:硬卧,4:软卧,1:硬座class TrainSpider(object):login_url = "https://kyfw.12306.cn/otn/resources/login.html"personal_url = "https://kyfw.12306.cn/otn/view/index.html"left_ticket_url = "https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc"confirm_passenger_url = "https://kyfw.12306.cn/otn/confirmPassenger/initDc"def __init__(self,from_station,to_station,train_date,trains,passengers):""":param from_station: 起始站:param to_station: 目的站:param train_date: 出发日期:param trains: 需要购买的车次。{"G529":["M","O"],"G403":["M","O"]}:param passengers: 乘客的姓名,需要为一个列表"""self.from_station = from_stationself.to_station = to_stationself.train_date = train_dateself.trains = trainsself.passengers = passengersself.selected_number = Noneself.selected_seat = None# 初始化站点所对应的代号self.station_codes = {}self.init_station_code()def init_station_code(self):with open("stations.csv", 'r', encoding='utf-8') as fp:reader = csv.DictReader(fp)for line in reader:name = line["name"]code = line['code']self.station_codes[name] = codedef login(self):driver.get(self.login_url)# 等待url是否变成个人中心的url,来判断是否登录成功WebDriverWait(driver,1000).until(EC.url_contains(self.personal_url))print("登录成功!")def search_left_ticket(self):driver.get(self.left_ticket_url)# 起始站的代号设置from_station_input = driver.find_element_by_id("fromStation")from_station_code = self.station_codes[self.from_station]driver.execute_script("arguments[0].value='%s'"%from_station_code,from_station_input)# 终点站的代号设置to_station_input = driver.find_element_by_id("toStation")to_station_code = self.station_codes[self.to_station]driver.execute_script("arguments[0].value='%s'" % to_station_code, to_station_input)# 时间设置train_date_input = driver.find_element_by_id("train_date")driver.execute_script("arguments[0].value='%s'" % self.train_date, train_date_input)# 执行查询操作search_btn = driver.find_element_by_id("query_ticket")search_btn.click()# 解析车次信息WebDriverWait(driver,1000).until(EC.presence_of_element_located((By.XPATH,"//tbody[@id='queryLeftTable']/tr")))train_trs = driver.find_elements_by_xpath("//tbody[@id='queryLeftTable']/tr[not(@datatran)]")is_searched = Falsewhile True:for train_tr in train_trs:infos = train_tr.text.replace("\n", " ").split(" ")number = infos[0]if number in self.trains:seat_types = self.trains[number]for seat_type in seat_types:if seat_type == "O":# 二等座count = infos[9]if count.isdigit() or count == '有':is_searched = Truebreakelif seat_type == 'M':# 一等座count = infos[8]if count.isdigit() or count == '有':is_searched = Truebreakif is_searched:self.selected_number = numberorder_btn = train_tr.find_element_by_xpath(".//a[@class='btn72']")order_btn.click()returndef confirm_passengers(self):WebDriverWait(driver,1000).until(EC.url_contains(self.confirm_passenger_url))# 先等待一下乘客标签显示出来了WebDriverWait(driver,1000).until(EC.presence_of_element_located((By.XPATH,"//ul[@id='normal_passenger_id']/li/label")))# 确认需要购买车票的乘客passenger_labels = driver.find_elements_by_xpath("//ul[@id='normal_passenger_id']/li/label")for passenger_label in passenger_labels:name = passenger_label.textif name in self.passengers:passenger_label.click()# 确认需要购买的席位信息seat_select = Select(driver.find_element_by_id("seatType_1"))seat_types = self.trains[self.selected_number]for seat_type in seat_types:try:self.selected_seat = seat_typeseat_select.select_by_value(seat_type)except NoSuchElementException:continueelse:break# 等待提交订单按钮可以被点击WebDriverWait(driver,1000).until(EC.element_to_be_clickable((By.ID,"submitOrder_id")))submit_btn = driver.find_element_by_id("submitOrder_id")submit_btn.click()# 判断模态对话框出现并且确认按钮可以点击了WebDriverWait(driver,1000).until(EC.presence_of_element_located((By.CLASS_NAME,"dhtmlx_window_active")))WebDriverWait(driver,1000).until(EC.element_to_be_clickable((By.ID,"qr_submit_id")))submit_btn = driver.find_element_by_id("qr_submit_id")while submit_btn:try:submit_btn.click()submit_btn = driver.find_element_by_id("qr_submit_id")except ElementNotVisibleException:breakprint("恭喜!%s车次%s抢票成功!"%(self.selected_number,self.selected_seat))def run(self):# 1. 登录self.login()# 2. 车次余票查询self.search_left_ticket()# 3. 确认乘客和车次信息self.confirm_passengers()def main():from_station = input("请输入出发地:")to_station = input("请输入目的地:")spider = TrainSpider(from_station,to_station,"2020-08-01",{"G529":["O","M"],"G111":["M"]},['杨靖智'])spider.run()if __name__ == '__main__':main()

使用selenium和chromedriver实现12306抢票相关推荐

  1. python实战 selenium+chrome玩转12306抢票

    文章目录 一.目标网站分析 1.1购票流程逐步分析 1.2网站细节分析 1.2.1 输入出发地和目标地的注意点 1.2.2 跳转页面的时候要加入显示等待 1.2.3 被淘汰的语法应该被替换掉 二.代码 ...

  2. 12306 抢票 python + selenium + chrome (二) 基础准备的软件和材料

    我使用的 vmware 14 + ubuntu 16  +  PyCharm  开发环境 12306抢票 python+selenium+chrome 实现一 12306抢票 python+selen ...

  3. python3+selenium实现12306抢票脚本

    文章目录 一. 环境配置 windows环境 mac.linux环境 二. 实现思路及代码 1. 查询票数 2. 登录 关于自动登录 3. 提交订单 4. 邮件提醒 5. 短信提醒 三.总结与分析 一 ...

  4. python+selenium实现12306抢票

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

  5. python编程实践(3):python+selenium实现12306抢票脚本

    又到了一年一度的春运时节,抢个票? 1.设计思路 如果我们要买一张火车票,我们会怎么做?打开12306,登陆,输入出发地和目的地,选择出行日期,然后点击查询,有余票的话就下单购买,没有票就点刷新或者等 ...

  6. Python selenium+pyautogui写的一个12306抢票

    用selenium+pyautogui写的一个12306抢票 `` 最近处于找工作阶段,在家里闲着无聊,写了一个12306的抢票,还很简陋,也是第一次写文发帖,大佬勿喷. 首先导入模块部分.有些外部库 ...

  7. 爬虫实战篇---12306抢票爬虫

    12306抢票爬虫 先直接上一下效果图吧: 图片上信息是抢票成功后的界面 1.技术路线 selenium + chromedriver 2.思路分析 (1).模拟浏览器登录抢票界面,手动进行登录 (2 ...

  8. python抢票web端_python+Splinter实现12306抢票功能

    本文实例为大家分享了python实现12306抢票功能的具体代码,供大家参考,具体内容如下 源码记录如下: #!/usr/bin/env python # _*_ coding:utf-8 _*_ # ...

  9. 通过python实现12306抢票

    铁路12306抢票系统 ​ #!/usr/bin/env python # -*- coding: utf-8 -*- """ 通过splinter刷12306火车票 进 ...

  10. python爬虫抢火车票_如何用python写一个简单的12306抢票软件|python 爬火车票 教程...

    python 如果抓取验证码图片 类似12306的登录验证码图片 这个以前做次.最大的麻烦是码的识别算法的识别率太低.12306那种网站登陆错3次就限制你20分钟.所以除非你有33%以上的识别率否则不 ...

最新文章

  1. thinkphp5的目录结构和命名规范
  2. composer 更新国内镜像地址
  3. Apollo后台配置:添加部门
  4. Java 8 Lambda演练
  5. Ubuntu开发环境配置--- 安装chrome浏览器
  6. Vijos P1786 质因数分解【质因数分解】
  7. sublime3中文乱码解决包ConvertToUTF8.zip
  8. 介绍下Javascript原型和原型链的特点?
  9. HashSet、TreeSet、LinkedHashSet的区别
  10. 开源微信小程序源码+小程序游戏代码附搭建框架教程
  11. 信息安全管理体系(ISMS)
  12. wordpress设置首页为特定页
  13. 创建一个新用户身份为计算机管理员,以Guest账户身份创建一个管理员
  14. python将字典按行或按列写入csv文件
  15. RL(Chapter 3): Finite Markov Decision Processes (有限马尔可夫决策过程)
  16. Arcgis使用教程(十)ARCGIS地图制图之经纬网格添加
  17. greenplum数据库的使用
  18. Android设备唯一标识符ID
  19. Mysql字段类型转换
  20. JQuery DataGrid 中文文档

热门文章

  1. 动态拨号主机多IP随机分配拨号自动分配
  2. Zabbix5.0监控CenterOS(RPM版)
  3. 【已解决】更新到MacOS Catalina 10.15后,VMware Fusion 虚拟机黑屏以及无法添加辅助功能的问题
  4. MacOS获取辅助功能权限控制鼠标点击事件
  5. 小程序中 icon 颜色自定义解决方案
  6. 七夕表白攻略:教你用自己的专业说情话,成功率100%,我只能帮你们到这里了啊~(程序员系列)
  7. 内容公链Contentos首席科学家不建议刚毕业的年轻人直接从事区块链开发
  8. 3D迷宫(DirextX9)
  9. 转载 测试开发岗--高频知识整理
  10. 爬虫入门 手写一个Java爬虫