Python练习:自动购买高铁票

题目

请大家写一个Python程序,使用selenium库,

能够自动登录12306网站购买明天从 北京南上海虹桥 的2等座高铁票。

程序运行的时候,提示用户输入要购票的车次,可以填写多个,以逗号隔开。

程序只要发现其中有任意一个可以购买的车票,都要立即进行购买操作



答案与解析

















































答案

这个题目考察的重点是:

  • 如何选择比较复杂的界面元素
  • 如何对web自动化程序进行调试
# 请使用Python3.6以上的版本运行此程序

import sys
import time
from selenium import webdriver

inputTrains = input('请输入您要要购票的车次,可以填写多个,以逗号隔开\n:')

# 将输入的车次存放到列表中,便于查找
trains = inputTrains.split(',')
targetTrainList = [train.strip()  for train in trains]

confirm = input(f'\n\n您要购买的车次是:{targetTrainList} \n 确认请输入yes后回车:')

if confirm.strip().lower() != 'yes':
    sys.exit(2)



# 如果发现没有票,就每隔10秒刷新一次网页
retry_rate = 10


#  使用chrome浏览器进行自动化,
#  注意下载好 chrome浏览器的 webdriver 的驱动程序,
#  并且放到环境变量path的目录下面

#   webdriver.Chrome()
#  返回一个WebDriver 对象,通过它我们,可以对浏览器进行自动化
driver = webdriver.Chrome()

#   设置好缺省等待时间
driver.implicitly_wait(20)

#  打开 12306网址
driver.get('https://kyfw.12306.cn/otn/login/init')

input('''\n\n输入验证码的步骤不好自动化
请手工在在登录界面,输入用户名、密码和验证码,登录
登录成功后按回车''')

driver.get('https://kyfw.12306.cn/otn/leftTicket/init')


# 出发地编辑框输入北京南。

#  driver找到了该元素的话,就会返回一个表示该元素的WebElement对象。
fromStation = driver.find_element_by_id('fromStationText')
fromStation.click()
fromStation.clear()
fromStation.send_keys('北京南\n')

# 目的地编辑框输入上海虹桥
toStation = driver.find_element_by_id('toStationText')
toStation.click()
toStation.clear()
toStation.send_keys('上海虹桥\n')



# 下面的css 选择表达式表示选择
# id 为date_range的元素里面的第二个li 节点
# 第2个li对应的就是界面上第个标签页,就是明天的车次信息
query = driver.find_element_by_css_selector(
    '#date_range li:nth-child(2)')


# 循环查询是否有余票
while True:

    # 点击搜索车次
    query.click()

    # 查看2等座有票的的车次
    resultList = driver.find_elements_by_xpath(
        '//*[@id="queryLeftTable"]//td[4][@class]/../td[1]//a')

    # 2等座有票的的车次里面看看是否有我们要购买的车次
    for findTrain in resultList:
        trainname = findTrain.text

        # 如果发现了
        if trainname in targetTrainList:

            print(f'发现{trainname}有余票')
            # 回溯到上层节点,再选最后一列,那是订购按钮
            findTrain.find_element_by_xpath(
                '../../../../../td[last()]').click()

            driver.find_element_by_id('normalPassenger_1').click()
            driver.find_element_by_id('submitOrder_id').click()

            input('请付款后,再关闭本程序!!!!')

            sys.exit()


    print(f"{time.strftime('%H:%M:%S')} 没有可购买票")

    # 过会儿再试一次
    time.sleep(retry_rate)