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中的defaultdict模块和namedtuple模块的简单入门指南
Apr 01 Python
Python和Perl绘制中国北京跑步地图的方法
Mar 03 Python
利用Python为iOS10生成图标和截屏
Sep 24 Python
python 捕获shell脚本的输出结果实例
Jan 04 Python
python解析基于xml格式的日志文件
Feb 25 Python
详解Python自建logging模块
Jan 29 Python
python微信跳一跳系列之棋子定位颜色识别
Feb 26 Python
python实现word 2007文档转换为pdf文件
Mar 15 Python
Python绘图Matplotlib之坐标轴及刻度总结
Jun 28 Python
Python 异步协程函数原理及实例详解
Nov 13 Python
python 中的[:-1]和[::-1]的具体使用
Feb 13 Python
详解Windows下PyCharm安装Numpy包及无法安装问题解决方案
Jun 18 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检查是否是ajax请求的方法
2015/04/16 PHP
php结合web uploader插件实现分片上传文件
2016/05/10 PHP
php获取目录中所有文件名及判断文件与目录的简单方法
2017/03/04 PHP
PHP无限极分类函数的实现方法详解
2017/04/15 PHP
PHP实现文件上传功能实例代码
2017/05/18 PHP
PHP的mysqli_stmt_init()函数讲解
2019/01/24 PHP
原生PHP实现导出csv格式Excel文件的方法示例【附源码下载】
2019/03/07 PHP
基于JQuery的数字改变的动画效果--可用来做计数器
2010/08/11 Javascript
js输出列表实现代码
2010/09/12 Javascript
映彩衣的js随笔(js图片切换效果)
2011/07/31 Javascript
JS代码优化技巧之通俗版(减少js体积)
2011/12/23 Javascript
JavaScript数字和字符串转换示例
2014/03/26 Javascript
jQuery unbind()方法实例详解
2016/01/19 Javascript
前端框架Vue.js构建大型应用浅析
2016/09/12 Javascript
纯JS打造网页中checkbox和radio的美化效果
2016/10/13 Javascript
Vue-Access-Control 前端用户权限控制解决方案
2017/12/01 Javascript
bootstrap+jquery项目引入文件报错的解决方法
2018/01/22 jQuery
Vue核心概念Action的总结
2019/01/18 Javascript
微信小程序如何连接Java后台
2019/08/08 Javascript
微信小程序点击生成朋友圈分享图(遇到的坑)
2020/06/17 Javascript
请求时token过期自动刷新token操作
2020/09/11 Javascript
Map与WeakMap类型在JavaScript中的使用详解
2020/11/18 Javascript
[01:00:59]VP VS VG Supermajor小组赛胜者组第二轮 BO3第二场 6.2
2018/06/03 DOTA
python相似模块用例
2016/03/04 Python
在Pycharm中调试Django项目程序的操作方法
2019/07/17 Python
python实现12306登录并保存cookie的方法示例
2019/12/17 Python
使用python图形模块turtle库绘制樱花、玫瑰、圣诞树代码实例
2020/03/16 Python
Python socket处理client连接过程解析
2020/03/18 Python
基于Python实现体育彩票选号器功能代码实例
2020/09/16 Python
Python基于opencv的简单图像轮廓形状识别(全网最简单最少代码)
2021/01/28 Python
HTML5资源预加载(Link prefetch)详细介绍(给你的网页加速)
2014/05/07 HTML / CSS
英国鲜花递送:Blossoming Gifts
2020/07/10 全球购物
小学毕业典礼演讲稿
2014/09/09 职场文书
追悼会答谢词范文
2015/09/29 职场文书
Python中的变量与常量
2021/11/11 Python
Win11怎么跳过联网验机 ?Win11跳过联网验机激活教程
2022/04/05 数码科技