如何用python编写火车抢票助手

前几天跟朋友说打算写一个抢票助手,最后由于某些原因念头打消了。

可就在昨天晚上,才隐约记起一年前的自己曾经说过:一年后我一定要写一个12306的抢票助手!瞬间激情澎湃,甚至已经是快临近凌晨时便开始动工,可天意不能违,12306晚上11点便开始维护,后续阶段程序不得不暂停;只能今天继续完成最后一部分,幸好自己进度还是可以的,刚刚debug完毕就给大家分享一下!


开头肯定是老套路

首先我们要安装python的编译环境,推荐使用python3.6(本文章使用的是python3);

python下载安装网址:https://www.python.org/


安装python的第三方工具库selenium

selenium是Web 应用程序自动化测试工具,可模拟人为操作实现自动化的强大的工具库


第二步:

下载chrome自动化驱动,链接:

http://chromedriver.storage.googleapis.com/index.html


chrome自动化驱动与chrome浏览器版本是有相对应的版本;chrome浏览器最新版本对应驱动版本2.35

具体驱动与浏览器版本映射表查看链接:

http://blog.csdn.net/huilan_same/article/details/51896672


第三步:进入主题,编写代码


引入库文件

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time


编写主要代码

us=input('请输入12306账号:')
pw=input('请输入12306密码:')
fromStation=input('请输入出发站点:')
toStation=input('请输入目的站点:')
date=input('请输入出发时间(格式:2018-02-02):')
number=input('请输入列车号(区别大小写):')
passenger=input('请输入乘车人姓名(格式:姓名(学生)或者姓名):')
driver=webdriver.Chrome()#加载chrome驱动
login(us,pw)#登录
query()#查询
buyTicket()#抢票
confirm()#购票


乘车人姓名要预先在12306网址上存在,并且要按红色方框内容填写


编写一个判断xpath是否存在的函数XpathExist(driver,xpath)

def XpathExist(driver,xpath):
   """
   检查xpath是否存在
   :param driver,xpath:
   :return:
   """

   try:
       driver.find_element_by_xpath(xpath)#若不存在会抛出异常
       return True
   except:
       return False


编写登录12306函数login(us,pw)

#12306登录
def login(us,pw):
   driver.get("https://kyfw.12306.cn/otn/login/init")#打开网址
   username= driver.find_element_by_xpath('//*[@id="username"]')#获取用户名的位置
   password=driver.find_element_by_xpath('//*[@id="password"]')#获取密码的位置
   username.send_keys(us)#输入用户名
   password.send_keys(pw)#输入密码
   while True:
       #链接跳转则,登录成功
       if driver.current_url=='https://kyfw.12306.cn/otn/index/initMy12306':
           break


编写12306查询函数query()


难点:主要就在输入出发站跟目的站,12306反爬技术很强大,自己在这里调试了两个小时,最后发现要先点击一下,再清除内容,再输入内容,再按键盘Down键,最后再按tab键才可以;时间则要用js处理。


#12306查询
def query():
   driver.get('https://kyfw.12306.cn/otn/leftTicket/init')#打开网址
   fromStationText=driver.find_element_by_xpath('//*[@id="fromStationText"]')#获取出发点的位置
   toStationText=driver.find_element_by_xpath('//*[@id="toStationText"]')#获取目的地的位置
   #要先点击一下,在清楚输入框的内容,再输入内容,再按键盘Down键,最后再按tab键
   fromStationText.click()
   fromStationText.clear();
   fromStationText.send_keys(fromStation)
   fromStationText.send_keys(Keys.DOWN)
   fromStationText.send_keys(Keys.TAB)
   toStationText.click()
   toStationText.clear();
   toStationText.send_keys(toStation)
   toStationText.send_keys(Keys.DOWN)
   toStationText.send_keys(Keys.TAB)
      #用js输入时间
   js="document.getElementById('train_date').value='"+date+"'"
   driver.execute_script(js)
   time.sleep(1)#等待1s
   while True:
       xpath='//*[@id="query_ticket"]'
       if XpathExist(driver,xpath):
           try:
               driver.find_element_by_xpath(xpath).click()#点击查询按钮
               print("查询中...")
               break
           except:
               continue


抢票函数buyTicket()

#抢票
def buyTicket():
   while True:
       try:

           xpath="//a[text()='"+number+"']/../../../../../td[13]/a"
           if driver.current_url=='https://kyfw.12306.cn/otn/confirmPassenger/initDc':
               break
           if XpathExist(driver,xpath):
               order=driver.find_element_by_xpath(xpath)
               order.click()
               print("抢票中...")
           else:
               xpath='//*[@id="query_ticket"]'
               if XpathExist(driver,xpath):
                   try:
                       driver.find_element_by_xpath(xpath).click()
                   except:
                       print("重新点击")

       except:
           continue


确认购票confirm()


#确认购票
def confirm():
   while True:
       try:
           xpath='//*[@id="content_defaultwarningAlert_hearder"]/a'
           if XpathExist(driver,xpath):
               driver.find_element_by_xpath(xpath)
               print(driver.find_element_by_xpath(xpath))
           else:
               xpath='//label[text()="'+passenger+'"]'
               while True:
                   try:
                       driver.find_element_by_xpath(xpath).click()
                       break
                   except:
                       continue
               xpath='//*[@id="dialog_xsertcj_ok"]'
               if XpathExist(driver,xpath):
                   print("确认弹出窗口中...")
                   while True:
                       try:
                           driver.find_element_by_xpath(xpath).click()
                           break
                       except:
                           break
               xpath='//*[@id="content_defaultwarningAlert_title"]'
               if XpathExist(driver,xpath):
                    print('目前没票')
               else:
                   print("点击成功")
                   driver.find_element_by_xpath('//*[@id="submitOrder_id"]').click()
                   while True:
                       try:
                           if driver.current_url!='https://kyfw.12306.cn/otn/confirmPassenger/initDc':
                               print("抢票成功,请及时付款")
                               break
                           xpath='//*[@id="orderResultInfo_id"]/div/span'
                           if XpathExist(driver,xpath):
                               print('抢票失败')
                               break
                           driver.find_element_by_xpath('//*[@id="qr_submit_id"]').click()

                       except:
                           continue
                   break
       except:
           continue


由于想到这几天大家要开始第一轮抢票模式,所以刚刚写完的程序,没有经过大量测试,我便匆匆忙忙发布上来供大家分享;如果在使用中发现有bug,欢迎在文章留言,我会及时的处理!

为了不懂编程的小伙伴,同时我也对应发布了可执行的exe文件。

展开阅读全文

没有更多推荐了,返回首页