欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python+Splinter实现12306抢票功能

程序员文章站 2023-11-02 14:34:10
本文实例为大家分享了python实现12306抢票功能的具体代码,供大家参考,具体内容如下 源码记录如下: #!/usr/bin/env python # _...

本文实例为大家分享了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信息')

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