import time
from selenium import webdriver
from selenium.common import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from station_name import get_station
from selenium.webdriver.support.ui import Select
class QiangPiao:
#登录网址
login_url = 'https://kyfw.12306.cn/otn/resources/login.html'
station_info = {}
#初始化driver
def __init__(self, driver,from_station,to_station, date_station,trains,passenger_name_lst):
self.driver = driver
self.from_station = from_station
self.to_station = to_station
self.date_station = date_station
self.trains = trains
self.passenger_name_lst = passenger_name_lst
self.seat_type = None
for station_name, station_code in get_station():
self.station_info[station_name] = station_code
#打开网址
def open(self):
self.driver.get(self.login_url)
self.driver.maximize_window()
#扫描登录
def login(self):
WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="toolbar_Div"]/div[3]/div[2]/ul/li[2]/a'))).click()
WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.ID, 'gerenzhongxin')))
#查询车票
def search(self):
self.driver.find_element(By.ID, 'link_for_ticket').click()
from_station_code = self.station_info[self.from_station]
to_station_code = self.station_info[self.to_station]
from_station_element = WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.ID, 'fromStation')))
to_station_element = self.driver.find_element(By.ID, 'toStation')
train_date = self.driver.find_element(By.ID, 'train_date')
self.driver.execute_script('arguments[0].value = "%s"' % from_station_code, from_station_element)
self.driver.execute_script('arguments[0].value = "%s"' % to_station_code, to_station_element)
train_date.clear()
train_date.send_keys(self.date_station)
is_flag = False #标记是否有余票
is_select_fram_and_to = False #标记是否已勾选出发地和目的地复选框
while True:
self.driver.find_element(By.ID, 'query_ticket').click()
# 勾选出发和目的地
if not is_select_fram_and_to:
WebDriverWait(self.driver,10).until(EC.element_to_be_clickable((By.ID, f"cc_from_station_{self.from_station}"))).click()
WebDriverWait(self.driver,10).until(EC.element_to_be_clickable((By.ID, f"cc_to_station_{self.to_station}"))).click()
is_select_fram_and_to = True
#获取车次
WebDriverWait(self.driver, 1000).until(
EC.presence_of_element_located((By.XPATH, '//tbody[@id="queryLeftTable"]/tr[not(@datatran)]')))
train_infos = self.driver.find_elements(By.XPATH, '//tbody[@id="queryLeftTable"]/tr[not(@datatran)]')
#分别遍历每个车次
for train_info in train_infos:
infos = train_info.text.replace('\n', ' ').split(' ')
train_no = infos[0]
if train_no in self.trains:
#根据key获取值 席别是一个列表
seat_types = self.trains[train_no]
for seat_type in seat_types: #遍历席位的列表
if seat_type == 'O': #说明是二等座
count = infos[11] #索引为11的是二等座
if count.isdigit() or count == '有':#有票就可以执行单击预定
is_flag = True
self.seat_type = seat_type
break
elif seat_type == 'M': #说明是一等座
count = infos[10] #索引为10的是一等座
if count.isdigit() or count == '有':#有票就可以执行单击预定
is_flag = True
self.seat_type = seat_type
break
if is_flag:
order_btn = train_info.find_element(By.XPATH, './/a[@class="btn72"]')
order_btn.click()
return
def confirm(self):
submit_btn = WebDriverWait(self.driver, 1000).until(EC.element_to_be_clickable((By.ID, 'submitOrder_id')))
passengers = self.driver.find_elements(By.XPATH, '//ul[@id="normal_passenger_id"]/li/label')
for passenger in passengers: #分别遍历每一位乘车人
name = passenger.text #获取乘车人姓名
if name in self.passenger_name_lst:
passenger.click()
#确认席位
seat_select = Select(self.driver.find_element(By.ID, 'seatType_1'))
try:
seat_select.select_by_value(self.seat_type)
except NoSuchElementException:
pass
#提交订单
submit_btn.click()
ok_btn = WebDriverWait(self.driver, 1000).until(EC.element_to_be_clickable((By.ID, 'qr_submit_id')))
while True:
try:
ok_btn.click()
ok_btn = self.driver.find_element(By.ID, 'qr_submit_id')
except NoSuchElementException:
print("aaa")
break
except ElementNotInteractableException:
print("bbb")
# 如果仍不可交互,等一小会儿再试
break
print(self.seat_type)
if self.seat_type == 'O':
print('恭喜抢到车票了,坐席为二等坐!!!')
elif self.seat_type == 'M':
print('恭喜抢到车票了,坐席为一等坐!!!')
def start(self):
self.open()
self.login()
self.search()
self.confirm()
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from qiangpiao import QiangPiao
driver = webdriver.Chrome(service=Service('chromedriver.exe'))
qp = QiangPiao(driver,'上虞南','杭州东', '2026-07-16',{'G7588': ['O','M']}, ['胡渠洋']) #O是二等座,M是一等座
qp.start()
input('按任意键继续')