python+Splinter实现12306抢票功能


Posted in Python onSeptember 25, 2018

本文实例为大家分享了python实现12306抢票功能的具体代码,供大家参考,具体内容如下

源码记录如下:

#!/usr/bin/env python
# _*_ coding:utf-8 _*_

#!/usr/bin/env python
# _*_ coding:utf-8 _*_

from splinter.browser import Browser
from time import sleep
import os
# from selenium.webdriver.chrome.options import Options
import logging
from log_class import Logger # 需要一个logger库
import sys

reload(sys)
sys.setdefaultencoding('utf-8') # 防止由于Unicode编码与ASCII编码的不兼容造成错误

class BuyTicket(object):
  def __init__(self, username, passwd, order, passengers, seatType, ticketType, daytime, starts, ends):
    # 用户名 密码
    self.username = username
    self.passwd = passwd
    # 车次,选择第几趟,0则从上之下依次点击
    self.order = order
    # 乘客名
    self.passengers = passengers
    # 席位
    self.seatType = seatType
    self.ticketType = ticketType
    # 时间格式2018-02-05
    self.daytime = daytime
    # 起始地和终点
    self.starts = starts
    self.ends = ends

    self.login_url = 'https://kyfw.12306.cn/otn/login/init'
    self.initMy_url = 'https://kyfw.12306.cn/otn/index/initMy12306'
    self.ticket_url = 'https://kyfw.12306.cn/otn/leftTicket/init'
    # 浏览器名称
    self.driver_name = 'firefox' # chrome firefox
    # 火狐浏览器第三方驱动
    self.executable_path = os.getcwd()+'/geckodriver' # 获取工程目录下的火狐驱动 chromedriver

  def login(self):
    # 访问登录网址
    self.driver.visit(self.login_url)
    # 填充用户名
    self.driver.fill("loginUserDTO.user_name", self.username)
    # sleep(1)
    # 填充密码
    self.driver.fill("userDTO.password", self.passwd)
    logbticket.info("请手动输入验证码...")
    # print('请手动输入验证码...') # 目前没有自动验证码
    # 循环等待登录,登录成功,跳出循环
    while True:
      if self.driver.url != self.initMy_url:
        sleep(1)
      else:
        break

  def start_buy(self):
    # 这些设置都是必要的
    # chrome_options = Options()
    # chrome_options.add_argument("--no-sandbox")
    # chrome_options.add_argument("--disable-setuid-sandbox")
    # chrome_options.add_argument("disable-infobars") # 禁用网页上部的提示栏
    # self.driver = Browser(driver_name=self.driver_name, options=chrome_options, executable_path=self.executable_path)
    self.driver = Browser(driver_name=self.driver_name,
               executable_path=self.executable_path)
    # 设置窗口大小尺寸
    self.driver.driver.set_window_size(1400, 1000)
    # 用户登录
    self.login()
    # 进入选票网站
    self.driver.visit(self.ticket_url)
    try:
      logbticket.info("购票页面开始....")
      # print("购票页面开始....")
      # sleep(1)
      # 加载查询信息
      self.driver.cookies.add({"_jc_save_fromStation": self.starts})
      self.driver.cookies.add({"_jc_save_toStation": self.ends})
      self.driver.cookies.add({"_jc_save_fromDate": self.daytime})

      self.driver.reload()

      count = 0
      if self.order != 0:
        while self.driver.url == self.ticket_url:
          self.driver.find_by_text("查询").click()
          count = count+1
          logbticket.info("第 %d 次点击查询..." % count)
          # print("第 %d 次点击查询..." % count)
          # sleep(1)
          try:
            self.driver.find_by_text("预订")[self.order - 1].click() # 点击第几个“预订”
            sleep(1.5)
          except Exception as e: # e是Exception 的一个instance
            # print(e)
            # print("预订失败...")
            logbticket.error(e)
            logbticket.error("预订失败...")
            continue
      else:
        while self.driver.url == self.ticket_url:
          self.driver.find_by_text("查询").click()
          count += 1
          logbticket.info("第 %d 次点击查询..." % count)
          # print("第 %d 次点击查询..." % count)
          try:
            for i in self.driver.find_by_text("预订"):
              i.click()
              sleep(1)
          except Exception as e:
            # print(e)
            # print("预订失败...")
            logbticket.error(e)
            logbticket.error("预订失败...")
            continue

      # print("开始预订....")
      logbticket.info("开始预订....")
      # sleep(1)
      # self.driver.reload()
      sleep(1)
      # print("开始选择用户....")
      logbticket.info("开始选择用户....")
      for p in self.passengers:
        pg = self.driver.find_by_text(p) # .last.click()
        pg.last.click()
      # print("提交订单....")
      logbticket.info("提交订单....")
      sleep(1)
      i = 0
      while len(self.passengers) > 0:
        i = i + 1
        seat_id_string = "seatType_" + str(i)
        ticket_id_string = "ticketType_" + str(i)
        self.driver.find_by_xpath('//select[@id="%s"]/option[@value="%s"]'
                     % (seat_id_string, self.seatType)).first._element.click()
        self.driver.find_by_xpath('//select[@id="%s"]//option[@value="%s"]'
                     % (ticket_id_string, self.ticketType)).first._element.click()
        # self.driver.select("confirmTicketType", "3")
        self.passengers.pop()
        sleep(1)
      self.driver.find_by_id("submitOrder_id").click()
      # print("开始选座...")
      logbticket.info("开始选座...")
      sleep(1.5)
      # print("确认选座....")
      logbticket.info("确认选座....")
      self.driver.find_by_text("qr_submit_id").click()

    except Exception as e:
      # print(e)
      logbticket.error(e)


city = {"深圳": "%u6DF1%u5733%2CSZQ",
    "武汉": "%u6B66%u6C49%2CWHN",
    "随州": "%u968F%u5DDE%2CSZN"}

seatT = {"硬卧": "3",
     "软卧": "4",
     "硬座": "1",
     "二等座": "O",
     "一等座": "M",
     "商务座": "9"}

if __name__ == '__main__':
  # 用户名
  username = "xxxxxxxx"
  # 密码
  password = "xxxxxx"
  # 车次选择,0代表所有车次
  order = 13
  # 乘客名,比如passengers = ['丁小红', '丁小明']
  passengers = ["xxx", "xxx"]
  # 日期,格式为:'2018-01-20'
  daytime = "2018-04-05"
  # 出发地(需填写cookie值)
  starts = city["xx"] # 武汉
  # 目的地(需填写cookie值)
  ends = city["xx"] # 北京
  # 席别
  seatType = seatT["二等座"] # 二等座
  # 票种
  ticketType = "1" # 成人票

  logbticket = Logger("bticket.log", logging.DEBUG, logging.ERROR)

  BuyTicket(username, password, order, passengers, seatType, ticketType, daytime, starts, ends).start_buy()

火狐浏览器的驱动下载地址

logger库文件:

源代码如下:

#!/usr/bin/env python
# _*_ coding:utf-8 _*_

import logging


class Logger:
  def __init__(self, path, clevel=logging.DEBUG, Flevel=logging.DEBUG):
    self.logger = logging.getLogger(path)
    self.logger.setLevel(logging.DEBUG)
    fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')
    # 设置CMD日志
    sh = logging.StreamHandler()
    sh.setFormatter(fmt)
    sh.setLevel(clevel)
    # 设置文件日志
    fh = logging.FileHandler(path)
    fh.setFormatter(fmt)
    fh.setLevel(Flevel)
    self.logger.addHandler(sh)
    self.logger.addHandler(fh)

  def debug(self, message):
    self.logger.debug(message)

  def info(self, message):
    self.logger.info(message)

  def war(self, message):
    self.logger.warn(message)

  def error(self, message):
    self.logger.error(message)

  def cri(self, message):
    self.logger.critical(message)


if __name__ == '__main__':
  logyyx = Logger('yyx.log', logging.ERROR, logging.DEBUG)
  logyyx.debug('一个debug信息')
  logyyx.info('一个info信息')
  logyyx.war('一个warning信息')
  logyyx.error('一个error信息')
  logyyx.cri('一个致命critical信息')

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
一个简单的python程序实例(通讯录)
Nov 29 Python
深入理解python函数递归和生成器
Jun 06 Python
python进程管理工具supervisor的安装与使用教程
Sep 05 Python
Django中针对基于类的视图添加csrf_exempt实例代码
Feb 11 Python
python顺序的读取文件夹下名称有序的文件方法
Jul 11 Python
利用Django提供的ModelForm增删改数据的方法
Jan 06 Python
python读写csv文件的方法
Aug 13 Python
Flask框架搭建虚拟环境的步骤分析
Dec 21 Python
详解python UDP 编程
Aug 24 Python
使用Python实现音频双通道分离
Dec 25 Python
详解Open Folder as PyCharm Project怎么添加的方法
Dec 29 Python
Python3+Flask安装使用教程详解
Feb 16 Python
一百多行python代码实现抢票助手
Sep 25 #Python
python爬虫之自动登录与验证码识别
Jun 15 #Python
python使用matplotlib模块绘制多条折线图、散点图
Apr 26 #Python
python绘制多个曲线的折线图
Mar 23 #Python
python使用Matplotlib绘制分段函数
Sep 25 #Python
python使用Matplotlib画饼图
Sep 25 #Python
python使用Matplotlib画条形图
Mar 25 #Python
You might like
php IP及IP段进行访问限制的代码
2008/12/17 PHP
PHP中使用foreach和引用导致程序BUG的问题介绍
2012/09/05 PHP
PHP 面向对象程序设计(oop)学习笔记(一) - 抽象类、对象接口、instanceof 和契约式编程
2014/06/12 PHP
PHP之图片上传类实例代码(加了缩略图)
2016/06/30 PHP
PHP实现网页内容html标签补全和过滤的方法小结【2种方法】
2017/04/27 PHP
Ecshop 后台添加新功能栏目及管理权限设置教程
2017/11/21 PHP
Ajax 数据请求的简单分析
2011/04/05 Javascript
jquery(live)中File input的change方法只起一次作用的解决办法
2011/10/21 Javascript
用js替换除数字与逗号以外的所有字符的代码
2014/06/07 Javascript
js鼠标点击图片切换效果实现代码
2015/11/19 Javascript
webpack中引用jquery的简单实现
2016/06/08 Javascript
Javascript将数值转换为金额格式(分隔千分位和自动增加小数点)
2016/06/22 Javascript
浅谈jQuery为哪般去掉了浏览器检测
2016/08/29 Javascript
AngularJS 异步解决实现方法
2017/06/12 Javascript
阿里大于短信验证码node koa2的实现代码(最新)
2017/09/07 Javascript
Nuxt.js SSR与权限验证的实现
2018/11/21 Javascript
Jquery实现获取子元素的方法分析
2019/08/24 jQuery
如何在JavaScript中等分数组的实现
2020/12/13 Javascript
[58:21]DOTA2亚洲邀请赛 4.3 突围赛 Liquid vs VGJ.T 第二场
2018/04/04 DOTA
详解Python下Flask-ApScheduler快速指南
2018/11/04 Python
Python socket 套接字实现通信详解
2019/08/27 Python
Python实现线性插值和三次样条插值的示例代码
2019/11/13 Python
pycharm内无法import已安装的模块问题解决
2020/02/12 Python
Python将二维列表list的数据输出(TXT,Excel)
2020/04/23 Python
django models里数据表插入数据id自增操作
2020/07/15 Python
torchxrayvision包安装过程(附pytorch1.6cpu版安装)
2020/08/26 Python
基于python判断字符串括号是否闭合{}[]()
2020/09/21 Python
vivo智能手机官方商城:vivo
2016/09/22 全球购物
Lookfantastic葡萄牙官方网站:欧洲第一大化妆品零售商
2018/03/17 全球购物
公司管理建议书范文
2014/03/12 职场文书
市场营销工作计划书
2014/09/15 职场文书
迎国庆横幅标语
2014/10/08 职场文书
2014年圣诞节寄语
2014/12/08 职场文书
求职自荐信范文(优秀篇)
2015/03/27 职场文书
如何撰写出一份完美的商业计划书?
2019/07/12 职场文书
如何用 Python 子进程关闭 Excel 自动化中的弹窗
2021/05/07 Python