本程序的几个注意点:
1、selenium定位元素
2、登录时,输入验证码(难点),目前采用手动输入验证码
3、选择始发地和目的地(难点),需要结合js调试代码(还有一种,点击需要选择的地点,右键检查;即可调试)
from selenium import webdriver
from time import sleep
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
import winsound
class TrainTest(object):
def __init__(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.implicitly_wait(30)
def test_open_browser(self):
# 打开12306网站
self.driver.get('https://kyfw.12306.cn/otn/index/init')
# 点击“登录”按钮进入登录页,此处需要考虑登录元素的加载速度
WebDriverWait(self.driver, 5).until(EC.presence_of_element_located((By.ID, 'login_user')))
self.driver.find_element_by_id('login_user').click()
# 输入12306账号和密码,输入验证码,点击登录按钮
self.driver.find_element_by_id('username').clear()
self.driver.find_element_by_id('username').send_keys('XXXXXX')
self.driver.find_element_by_id('password').clear()
self.driver.find_element_by_id('password').send_keys('XXXXXXXX')
sleep(5) # 设置睡眠时间5秒,用来手动选择验证码
print("请回到页面选择对应的验证码图片……")
self.driver.find_element_by_id('loginSub').click()
# 点击“车票预订”按钮,跳转到车票预订页面,此处需要考虑“车票预订”元素的加载速度
WebDriverWait(self.driver, 5).until(EC.presence_of_element_located((By.LINK_TEXT, '车票预订')))
self.driver.find_element_by_link_text('车票预订').click()
# 选择始发地、目的地、出发时间、车程类型
self.driver.find_element_by_id('fromStationText').click()
# setTimeout(function(){debugger;}, 5000) 利用js代码冻结浏览器窗口
self.driver.find_element_by_css_selector('[title=杭州]').click()
self.driver.find_element_by_id('toStationText').click()
self.driver.find_element_by_css_selector('[title=北京]').click()
self.driver.find_element_by_id('train_date').click()
self.driver.find_element_by_css_selector('body > div.cal-wrap > div:nth-child(1) '
'> div.cal-cm > div:nth-child(24) > div').click()
self.driver.find_element_by_xpath('//input[@value="G"]').click()
# todo 选择非热门的城市
# 循环刷票
while True:
try:
# 点击查询按钮,查出票的信息
self.driver.find_element_by_id('query_ticket').click()
e = self.driver.find_element_by_id('ZE_5800000G560E') # ZY_5800000G560E
e.click()
if e.text in ['无','--']:
print('暂无余票')
sleep(1)
else:
# 有余票则抢票
print('yes')
# 点击“预订”按钮
self.driver.find_element_by_css_selector('#ticket_5j0000G16422 > td.no-br > a').click()
# 选择乘车人信息
self.driver.find_element_by_xpath('//ul[@id="normal_passenger_id"]/li[1]/input').click()
# 点击“提交订单”按钮
self.driver.find_element_by_id('submitOrder_id').click()
self.driver.find_element_by_link_text("确认").click()
# 抢票成功后,播放声音提示
winsound.Beep(600,1000000)
except:
pass
if __name__ == '__main__':
test = TrainTest()
test.test_open_browser()