from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, StaleElementReferenceException, NoSuchElementException
import time
import os
import json
# 创建结果目录
if not os.path.exists('screenshots'):
os.makedirs('screenshots')
# 书籍借阅状态记录器
class BookTracker:
def __init__(self):
self.borrowed_books = {}
self.processed_titles = {}
def mark_borrowed(self, title, row_index):
"""标记书籍已被借阅"""
self.borrowed_books[title] = True
self.processed_titles[title] = row_index
def is_borrowed(self, title):
"""检查书籍是否已被借阅"""
return self.borrowed_books.get(title, False)
def was_processed(self, title):
"""检查书籍是否已处理过"""
return title in self.processed_titles
def save_state(self):
"""保存借阅状态到文件"""
state = {
'borrowed': self.borrowed_books,
'processed': self.processed_titles
}
with open('borrow_state.json', 'w') as f:
json.dump(state, f)
def load_state(self):
"""从文件加载借阅状态"""
try:
with open('borrow_state.json', 'r') as f:
state = json.load(f)
self.borrowed_books = state.get('borrowed', {})
self.processed_titles = state.get('processed', {})
print(f"已加载借阅状态: {len(self.borrowed_books)}本书已借阅")
except (FileNotFoundError, json.JSONDecodeError):
self.borrowed_books = {}
self.processed_titles = {}
print("未找到状态文件,使用新状态")
# 创建书籍跟踪器
book_tracker = BookTracker()
book_tracker.load_state()
def refresh_page(section_name):
"""刷新当前页面"""
print(f"刷新[{section_name}]页面...")
driver.switch_to.default_content()
try:
# 重新进入目标页面
section_link = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.LINK_TEXT, section_name))
)
section_link.click()
time.sleep(2) # 等待页面加载
# 切换回iframe
WebDriverWait(driver, 10).until(
EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe"))
)
print("页面刷新完成")
except Exception as e:
print(f"刷新页面失败: {str(e)}")
driver.save_screenshot(f"screenshots/refresh_failed.png")
def batch_borrow_books(num_books=2):
"""批量借阅多本图书 - 增强稳定性的处理方法"""
print(f"\n开始批量借阅 {num_books} 本书")
books_borrowed = 0
attempt_count = 0
max_attempts = num_books * 3 # 最大尝试次数
if num_books <= 0:
print("借阅数量必须大于0")
return
while books_borrowed < num_books and attempt_count < max_attempts:
print(f"尝试 #{attempt_count + 1}: 当前已借阅 {books_borrowed}/{num_books}")
try:
# 刷新页面确保最新状态
if attempt_count > 0 or books_borrowed > 0:
refresh_page("所有图书")
# 获取所有可借阅的书籍行
book_rows = WebDriverWait(driver, 10).until(
EC.presence_of_all_elements_located((By.XPATH, "//tr[.//a[contains(text(), '借阅')]]"))
)
if not book_rows:
print("未找到可借阅的书籍,刷新页面")
refresh_page("所有图书")
attempt_count += 1
time.sleep(1)
continue
print(f"当前有 {len(book_rows)} 本可借阅的书籍")
found_books = False
for row_idx, row in enumerate(book_rows, start=1):
if books_borrowed >= num_books:
break
try:
# 获取书名和行位置
title_cell = row.find_element(By.XPATH, "./td[3]")
book_title = title_cell.text.strip()
if not book_title:
print(f"第{row_idx}行: 标题为空,跳过")
continue
# 跳过已处理或借阅的书籍
if book_tracker.was_processed(book_title):
print(f"已处理《{book_title}》,跳过")
continue
# 标记为已处理(无论成功与否)
book_tracker.processed_titles[book_title] = row_idx
found_books = True
print(f"尝试借阅第{row_idx}行: 《{book_title}》")
# 获取借阅按钮
borrow_btn = row.find_element(By.XPATH, ".//a[contains(text(), '借阅')]")
# 使用JavaScript点击确保点击有效
driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", borrow_btn)
time.sleep(0.3)
driver.execute_script("arguments[0].click();", borrow_btn)
# 处理借阅结果弹窗
try:
WebDriverWait(driver, 5).until(EC.alert_is_present())
alert = driver.switch_to.alert
alert_text = alert.text
alert.accept()
print(f"借阅结果: {alert_text}")
if "成功" in alert_text:
book_tracker.borrowed_books[book_title] = True
books_borrowed += 1
print(f"√ 成功借阅《{book_title}》({books_borrowed}/{num_books})")
else:
print(f"借阅失败《{book_title}》")
except TimeoutException:
print("未检测到借阅弹窗")
# 短时等待让页面更新
time.sleep(1.5)
# 每次借阅后保存状态
book_tracker.save_state()
# 如果尚未借满,跳出当前循环重新获取书籍列表
if books_borrowed < num_books:
break
except StaleElementReferenceException:
print("元素过时,重新获取书籍列表")
break
except NoSuchElementException:
print(f"第{row_idx}行: 元素未找到,跳过")
except Exception as e:
print(f"处理第{row_idx}行书籍时出错: {str(e)}")
break
# 如果没有找到可处理书籍
if not found_books:
print("本页无未处理的书籍,重置处理状态")
book_tracker.processed_titles = {}
book_tracker.save_state()
attempt_count += 1
time.sleep(1)
except Exception as e:
print(f"借阅过程中出错: {str(e)}")
attempt_count += 1
time.sleep(1.5)
print(f"批量借阅完成: 成功借阅 {books_borrowed}/{num_books} 本书")
book_tracker.save_state()
def batch_return_books():
"""批量归还所有可归还的图书 - 增强稳定性的处理方法"""
print("\n开始批量归还图书")
books_returned = 0
attempt_count = 0
max_attempts = 10
while attempt_count < max_attempts:
print(f"归还尝试 #{attempt_count + 1}: 当前已归还 {books_returned} 本")
try:
# 刷新页面确保最新状态
if attempt_count > 0:
refresh_page("图书借阅记录")
# 获取所有归还按钮
return_btns = WebDriverWait(driver, 10).until(
EC.presence_of_all_elements_located((By.XPATH, "//a[contains(text(), '归还')]"))
)
if not return_btns:
print("没有可归还的图书")
break
print(f"找到 {len(return_btns)} 本可归还的图书")
# 尝试归还第一本书
return_btn = return_btns[0]
# 获取书名
try:
book_title = return_btn.find_element(By.XPATH, "./ancestor::tr/td[3]").text.strip()
if not book_title:
book_title = "未知书籍"
except:
book_title = "未知书籍"
# 点击归还
driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", return_btn)
time.sleep(0.3)
driver.execute_script("arguments[0].click();", return_btn)
print(f"正在归还《{book_title}》")
# 处理归还弹窗
try:
WebDriverWait(driver, 5).until(EC.alert_is_present())
alert = driver.switch_to.alert
alert_text = alert.text
alert.accept()
print(f"归还结果: {alert_text}")
if "成功" in alert_text:
# 更新借阅状态
if book_title in book_tracker.borrowed_books:
del book_tracker.borrowed_books[book_title]
if book_title in book_tracker.processed_titles:
del book_tracker.processed_titles[book_title]
books_returned += 1
print(f"√ 成功归还《{book_title}》")
# 更新状态
book_tracker.save_state()
# 短时等待让页面更新
time.sleep(1.5)
else:
print(f"归还失败《{book_title}》")
except TimeoutException:
print("未检测到归还弹窗")
# 如果没有更多书籍,退出循环
if len(return_btns) <= 1:
break
except (StaleElementReferenceException, NoSuchElementException):
print("页面元素已更新,重新尝试...")
attempt_count += 1
time.sleep(1)
continue
except Exception as e:
print(f"归还失败: {str(e)}")
attempt_count += 1
time.sleep(1.5)
continue
finally:
attempt_count += 1
print(f"批量归还完成: 成功归还 {books_returned} 本书")
# 启动WebDriver并解决兼容性问题
def create_driver():
"""创建兼容的Edge WebDriver实例"""
try:
return webdriver.Edge()
except Exception as e:
print(f"创建WebDriver时出错: {str(e)}")
print("尝试兼容模式启动...")
# 设置兼容性选项
options = webdriver.EdgeOptions()
options.add_argument('--use-chromium')
options.add_argument('--disable-gpu')
options.add_argument('--disable-extensions')
options.add_argument('--disable-blink-features=AutomationControlled')
options.add_experimental_option('excludeSwitches', ['enable-automation'])
options.add_experimental_option('useAutomationExtension', False)
options.add_argument('--ignore-certificate-errors')
options.add_argument('--no-sandbox')
# 添加更多选项解决兼容性问题
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--start-maximized')
options.add_argument('--disable-infobars')
return webdriver.Edge(options=options)
# 主程序
def main():
global driver
try:
driver = create_driver()
driver.set_page_load_timeout(30)
driver.maximize_window()
print("Edge WebDriver 已启动")
print("打开图书馆系统")
driver.get("http://localhost:8080/library_war/")
driver.save_screenshot("screenshots/homepage.png")
time.sleep(1.5)
print("输入管理员账号")
admin_num = WebDriverWait(driver, 15).until(
EC.element_to_be_clickable((By.NAME, "adminNumber"))
)
admin_num.clear()
admin_num.send_keys("1001")
print("输入管理员密码")
admin_pwd = driver.find_element(By.NAME, "adminPwd")
admin_pwd.clear()
admin_pwd.send_keys("123")
driver.save_screenshot("screenshots/before_login.png")
# 点击登录按钮
print("尝试登录")
login_btn = driver.find_element(By.CSS_SELECTOR, ".login_btn")
login_btn.click()
time.sleep(1.5)
# 检查登录是否成功
try:
WebDriverWait(driver, 8).until(EC.element_to_be_clickable((By.LINK_TEXT, "所有图书")))
print("登录成功")
driver.save_screenshot("screenshots/after_login.png")
except:
print("登录失败或加载超时")
driver.save_screenshot("screenshots/login_failed.png")
raise Exception("登录失败")
# ------ 所有图书操作 ------
print("访问所有图书")
all_books = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.LINK_TEXT, "所有图书"))
)
all_books.click()
time.sleep(2) # 等待 iframe 加载
# 切换到 iframe
print("切换到图书列表iframe")
iframe = WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.XPATH, "//iframe"))
)
driver.switch_to.frame(iframe)
driver.save_screenshot("screenshots/book_list.png")
time.sleep(1)
# 批量借阅操作
batch_borrow_books(num_books=3)
# 返回父框架
driver.switch_to.default_content()
# ------ 查询图书操作 ------
print("进入查询图书")
query_books = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.LINK_TEXT, "查询图书"))
)
query_books.click()
time.sleep(1.5)
print("切换到查询图书iframe")
iframe = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//iframe"))
)
driver.switch_to.frame(iframe)
time.sleep(1)
driver.save_screenshot("screenshots/query_book.png")
# 搜索图书
print("搜索'三国演义'")
title_input = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.NAME, "title"))
)
title_input.clear()
title_input.send_keys("三国演义")
driver.find_element(By.ID, "sub_but").click()
print("搜索完成")
time.sleep(1.5)
# 保存搜索结果
driver.save_screenshot("screenshots/search_result.png")
# 返回父框架
driver.switch_to.default_content()
# ------ 上架新图书操作 ------
print("上架新图书")
new_book = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.LINK_TEXT, "上架新图书"))
)
new_book.click()
time.sleep(1.5)
print("切换到上架新书iframe")
iframe = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//iframe"))
)
driver.switch_to.frame(iframe)
time.sleep(1)
driver.save_screenshot("screenshots/add_book.png")
# 填写新书信息
print("填写图书信息")
book_info = {
"title": "贝加尔湖畔",
"isbn": "1222222",
"author": "呜呜呜",
"price": "80",
"sum": "10",
"introduction": "描述贝加尔湖的魅力"
}
for field, value in book_info.items():
try:
element = WebDriverWait(driver, 5).until(
EC.element_to_be_clickable((By.NAME, field))
)
element.clear()
element.send_keys(value)
time.sleep(0.3)
except Exception as e:
print(f"填写字段 {field} 失败: {str(e)}")
# 选择图书分类
print("选择图书分类")
try:
driver.find_element(By.CSS_SELECTOR, ".layui-unselect:nth-child(1)").click()
time.sleep(0.7)
driver.find_element(By.XPATH, "(//dd)[3]").click()
time.sleep(0.5)
except:
print("选择分类失败")
# 提交新书
print("提交新书")
try:
driver.find_element(By.CSS_SELECTOR, ".layui-btn:nth-child(1)").click()
print("新书添加已提交")
time.sleep(2.5)
driver.save_screenshot("screenshots/book_added.png")
except Exception as e:
print(f"提交失败: {str(e)}")
# 返回父框架
driver.switch_to.default_content()
# ------ 访问其他页面 ------
menu_items = ["最新图书列表", "下架图书列表"]
for item in menu_items:
print(f"访问: {item}")
try:
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.LINK_TEXT, item))
)
element.click()
time.sleep(1.5)
driver.save_screenshot(f"screenshots/{item}.png")
except Exception as e:
print(f"访问 {item} 失败: {str(e)}")
# ------ 图书借阅记录操作 ------
print("访问图书借阅记录")
try:
borrow_records = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.LINK_TEXT, "图书借阅记录"))
)
borrow_records.click()
time.sleep(1.5)
print("切换到借阅记录iframe")
iframe = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//iframe"))
)
driver.switch_to.frame(iframe)
time.sleep(1)
driver.save_screenshot("screenshots/borrow_records.png")
# 批量归还图书
batch_return_books()
driver.save_screenshot("screenshots/after_return.png")
except Exception as e:
print(f"访问借阅记录失败: {str(e)}")
# 返回父框架
driver.switch_to.default_content()
# ------ 所有图书操作 ------
print("再次访问所有图书")
try:
driver.find_element(By.LINK_TEXT, "所有图书").click()
time.sleep(1.5)
print("切换到图书列表iframe")
iframe = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//iframe"))
)
driver.switch_to.frame(iframe)
time.sleep(1)
driver.save_screenshot("screenshots/final_book_list.png")
# 下架图书
print("下架图书")
# 尝试定位有效的下架按钮
try:
# 尝试查找下架按钮
take_down_btn = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "(//button[contains(text(), '下架')])[1]"))
)
driver.execute_script("arguments[0].scrollIntoView();", take_down_btn)
# 获取书名用于记录
try:
book_title = take_down_btn.find_element(By.XPATH, "./ancestor::tr/td[3]").text.strip()
print(f"下架书籍: 《{book_title}》")
except:
book_title = "未知书籍"
take_down_btn.click()
print("下架请求已发送")
time.sleep(1.5)
# 处理下架弹窗
try:
WebDriverWait(driver, 3).until(EC.alert_is_present())
alert = driver.switch_to.alert
alert_text = alert.text
print(f"下架结果: {alert_text}")
alert.accept()
# 如果下架的是已借阅书籍,更新状态
if book_title in book_tracker.borrowed_books:
del book_tracker.borrowed_books[book_title]
book_tracker.save_state()
except TimeoutException:
print("没有检测到下架弹窗")
except:
print("无法找到下架按钮,跳过此操作")
except Exception as e:
print(f"最后图书操作失败: {str(e)}")
# ------ 读者管理操作 ------
print("\n开始读者管理操作")
# 1. 访问所有读者页面(但不操作)
print("访问所有读者页面")
driver.switch_to.default_content()
all_readers = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.LINK_TEXT, "所有读者"))
)
all_readers.click()
time.sleep(1.5)
# 切换到iframe查看页面
print("切换到读者列表iframe")
iframe = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//iframe"))
)
driver.switch_to.frame(iframe)
time.sleep(1)
driver.save_screenshot("screenshots/all_readers_view.png")
driver.switch_to.default_content() # 立即切回主框架
# 2. 进入查询读者页面进行查询
print("进入查询读者页面")
query_reader = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.LINK_TEXT, "查询读者"))
)
query_reader.click()
time.sleep(1.5)
# 切换到iframe(重新定位iframe)
print("切换到查询读者iframe")
query_iframe = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//iframe"))
)
driver.switch_to.frame(query_iframe)
time.sleep(1)
# 查询读者:按管理员编号搜索
print("查询读者(管理员编号:1003)")
try:
# 使用更具体的定位方式
admin_number_input = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//input[@name='adminNumber']"))
)
admin_number_input.clear()
admin_number_input.send_keys("1003")
# 使用JavaScript输入值确保成功
driver.execute_script(f"arguments[0].value='1003';", admin_number_input)
# 定位并点击搜索按钮
search_btn = WebDriverWait(driver, 5).until(
EC.element_to_be_clickable((By.ID, "sub_but"))
)
search_btn.click()
print("搜索已提交")
time.sleep(1.5)
driver.save_screenshot("screenshots/query_reader_result.png")
except Exception as e:
print(f"查询读者失败: {str(e)}")
# 保存错误截图
driver.save_screenshot("screenshots/query_reader_error.png")
# 输出当前页面源码帮助调试
print("当前页面源码:\n", driver.page_source[:1000])
# 3. 进入添加读者页面添加读者
driver.switch_to.default_content()
print("进入添加读者页面")
add_reader = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.LINK_TEXT, "添加读者"))
)
add_reader.click()
time.sleep(1.5)
# 切换到添加读者iframe(重新定位iframe)
print("切换到添加读者iframe")
add_iframe = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//iframe"))
)
driver.switch_to.frame(add_iframe)
time.sleep(1)
driver.save_screenshot("screenshots/add_reader_page.png")
# 填写读者信息
print("填写读者信息")
reader_info = {
"adminName": "测试读者",
"adminPwd": "test123",
"adminNumber": "20250606"
}
for field, value in reader_info.items():
try:
element = WebDriverWait(driver, 5).until(
EC.element_to_be_clickable((By.XPATH, f"//input[@name='{field}']"))
)
element.clear()
element.send_keys(value)
# 使用JavaScript确保值已输入
driver.execute_script(f"arguments[0].value='{value}';", element)
time.sleep(0.3)
except Exception as e:
print(f"填写字段 {field} 失败: {str(e)}")
# 提交读者信息
print("提交读者信息")
try:
submit_btn = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, ".layui-btn:nth-child(1)"))
)
submit_btn.click()
print("读者添加已提交")
time.sleep(2.5)
driver.save_screenshot("screenshots/reader_added.png")
except Exception as e:
print(f"提交读者失败: {str(e)}")
# 4. 再次回到查询读者页面查询新添加的读者
driver.switch_to.default_content()
print("再次查询读者(验证添加结果)")
driver.find_element(By.LINK_TEXT, "查询读者").click()
time.sleep(1.5)
# 切换到iframe(重新定位iframe)
print("切换到查询读者iframe")
query_iframe = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//iframe"))
)
driver.switch_to.frame(query_iframe)
time.sleep(1)
# 重新定位输入框并搜索
print(f"查询读者(管理员编号:{reader_info['adminNumber']})")
try:
admin_number_input = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//input[@name='adminNumber']"))
)
admin_number_input.clear()
admin_number_input.send_keys(reader_info["adminNumber"])
# 使用JavaScript确保值已输入
driver.execute_script(f"arguments[0].value='{reader_info['adminNumber']}';", admin_number_input)
search_btn = WebDriverWait(driver, 5).until(
EC.element_to_be_clickable((By.ID, "sub_but"))
)
search_btn.click()
print("搜索已提交")
time.sleep(1.5)
driver.save_screenshot("screenshots/query_new_reader_result.png")
except Exception as e:
print(f"查询新读者失败: {str(e)}")
driver.save_screenshot("screenshots/query_new_reader_error.png")
print("当前页面源码:\n", driver.page_source[:1000])
# 5. 在查询结果页面直接点击进入读者详情
# 点击进入读者详情
print("点击进入用户界面")
try:
# 精确定位第四列中的"进入"链接按钮
enter_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//table//tr[1]/td[4]/a[contains(text(), '进入')]"))
)
# 滚动到元素并点击
driver.execute_script("arguments[0].scrollIntoView();", enter_button)
time.sleep(0.5)
# 记录当前窗口句柄
current_window = driver.current_window_handle
# 点击按钮
enter_button.click()
print("已点击进入按钮")
time.sleep(1)
# 处理窗口切换
try:
print("等待新窗口打开...")
WebDriverWait(driver, 10).until(lambda d: len(d.window_handles) > 1)
# 获取所有窗口句柄
all_handles = driver.window_handles
# 切换到新窗口
new_window = None
for handle in all_handles:
if handle != current_window:
new_window = handle
break
if new_window:
driver.switch_to.window(new_window)
print("已切换到新窗口")
# 等待页面加载完成
WebDriverWait(driver, 10).until(
lambda d: d.execute_script('return document.readyState') == 'complete')
# 保存截图
driver.save_screenshot("screenshots/reader_detail.png")
# 获取页面标题确认是否成功
print(f"读者详情页面标题: {driver.title}")
# 记录当前窗口句柄(新窗口)
user_window = driver.current_window_handle
# 在新窗口中执行用户操作
print("开始执行用户界面操作")
# --- 用户操作: 访问所有图书 ---
print("访问用户界面的所有图书")
try:
# 等待所有图书菜单出现
all_books_menu = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.LINK_TEXT, "所有图书"))
)
all_books_menu.click()
print("已点击所有图书菜单")
time.sleep(1.5)
# 切换到图书列表iframe
iframe = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//iframe"))
)
driver.switch_to.frame(iframe)
print("已切换到图书列表iframe")
driver.save_screenshot("screenshots/user_book_list.png")
time.sleep(1)
# 在用户界面批量借阅书籍(最多3本)
print("在用户界面批量借阅书籍")
batch_borrow_books(num_books=3)
# 返回主框架
driver.switch_to.default_content()
time.sleep(1)
# --- 用户操作: 查询图书 ---
print("访问用户界面的查询图书")
query_books_menu = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.LINK_TEXT, "查询图书"))
)
query_books_menu.click()
print("已点击查询图书菜单")
time.sleep(1.5)
# 切换到查询图书iframe
iframe = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//iframe"))
)
driver.switch_to.frame(iframe)
print("已切换到查询图书iframe")
time.sleep(1)
# 搜索《活着》
print("搜索图书‘活着’")
title_input = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.NAME, "title"))
)
title_input.clear()
title_input.send_keys("活着")
driver.find_element(By.ID, "sub_but").click()
print("搜索完成")
time.sleep(1.5)
driver.save_screenshot("screenshots/user_search_result.png")
# 返回主框架
driver.switch_to.default_content()
time.sleep(1)
# --- 用户操作: 图书借阅记录 ---
print("访问用户界面的图书借阅记录")
borrow_records_menu = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.LINK_TEXT, "图书借阅记录"))
)
borrow_records_menu.click()
print("已点击图书借阅记录菜单")
time.sleep(1.5)
# 切换到借阅记录iframe
iframe = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//iframe"))
)
driver.switch_to.frame(iframe)
print("已切换到借阅记录iframe")
time.sleep(1)
driver.save_screenshot("screenshots/user_borrow_records.png")
# 批量归还图书
batch_return_books()
# 返回主框架
driver.switch_to.default_content()
print("用户界面操作完成")
except Exception as e:
print(f"在用户界面操作过程中出错: {str(e)}")
driver.save_screenshot("screenshots/user_operation_error.png")
# 打印当前页面源码帮助调试
print("当前页面源码:\n", driver.page_source[:2000])
# 关闭新窗口,返回到主窗口(管理员界面)
print("关闭用户界面窗口")
driver.close()
print("已关闭用户窗口")
driver.switch_to.window(current_window)
print("已返回主窗口")
else:
print("未找到新窗口句柄")
except Exception as e:
print(f"窗口切换失败: {str(e)}")
except Exception as e:
print(f"点击进入按钮失败: {str(e)}")
driver.save_screenshot("screenshots/click_enter_error.png")
print("当前页面源码:\n", driver.page_source[:1000])
print("读者管理操作完成")
# 返回主框架并安全退出
driver.switch_to.default_content()
print("安全退出系统")
driver.find_element(By.LINK_TEXT, "安全退出").click()
time.sleep(1.5)
print("所有操作已完成!")
driver.save_screenshot("screenshots/all_operations_completed.png")
except Exception as e:
print(f"执行过程中出错: {str(e)}")
# 出错时截图保存
driver.save_screenshot("screenshots/error.png")
# 打印当前页面源码帮助调试
print("当前页面源码:\n", driver.page_source[:2000])
raise
finally:
# 保存借阅状态
book_tracker.save_state()
# 添加最终截图
driver.save_screenshot("screenshots/final.png")
# 添加暂停便于查看结果
input("按Enter键结束测试...")
if driver:
driver.quit()
print("浏览器已关闭")
if __name__ == "__main__":
main()