Add locator helper module and enhance main script for element interaction
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -11,4 +11,5 @@ temp
|
|||||||
tmpclaude-*
|
tmpclaude-*
|
||||||
*.log
|
*.log
|
||||||
*workspace*
|
*workspace*
|
||||||
*.png
|
*.png
|
||||||
|
data/
|
||||||
|
|||||||
171
locator_helper.py
Normal file
171
locator_helper.py
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
"""
|
||||||
|
元素定位辅助工具 - 用于快速验证定位是否有效
|
||||||
|
"""
|
||||||
|
from playwright.sync_api import Page, Frame, Locator
|
||||||
|
|
||||||
|
|
||||||
|
def debug_locator(frame: Frame, locator: Locator, timeout: int = 5000):
|
||||||
|
"""
|
||||||
|
调试定位器 - 检查定位是否有效并显示详细信息
|
||||||
|
|
||||||
|
参数:
|
||||||
|
frame: 页面或iframe对象
|
||||||
|
locator: 定位器对象
|
||||||
|
timeout: 超时时间(毫秒)
|
||||||
|
|
||||||
|
返回:
|
||||||
|
bool: 定位是否成功
|
||||||
|
"""
|
||||||
|
print(f"\n验证定位: {locator}")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 检查数量
|
||||||
|
count = locator.count()
|
||||||
|
print(f"元素数量: {count}")
|
||||||
|
|
||||||
|
if count == 0:
|
||||||
|
print("✗ 未找到任何匹配元素")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 检查第一个元素是否可见
|
||||||
|
first_visible = locator.first.is_visible(timeout=timeout)
|
||||||
|
print(f"第一个元素可见: {first_visible}")
|
||||||
|
|
||||||
|
# 获取文本内容
|
||||||
|
for i in range(min(3, count)): # 最多显示3个
|
||||||
|
element = locator.nth(i)
|
||||||
|
try:
|
||||||
|
if element.is_visible(timeout=1000):
|
||||||
|
text = element.inner_text(timeout=1000)
|
||||||
|
print(f" 元素{i + 1}文本: {text[:100] if len(text) > 100 else text}")
|
||||||
|
else:
|
||||||
|
print(f" 元素{i + 1}: 存在但不可见")
|
||||||
|
except:
|
||||||
|
print(f" 元素{i + 1}: 无法获取信息")
|
||||||
|
|
||||||
|
print("=" * 50)
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"✗ 验证失败: {e}")
|
||||||
|
print("=" * 50)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def try_multiple_locators(frame: Frame, selectors: list[str], timeout: int = 5000) -> Locator:
|
||||||
|
"""
|
||||||
|
尝试多个选择器,返回第一个有效的定位器
|
||||||
|
|
||||||
|
参数:
|
||||||
|
frame: 页面或iframe对象
|
||||||
|
selectors: 选择器列表
|
||||||
|
timeout: 超时时间(毫秒)
|
||||||
|
|
||||||
|
返回:
|
||||||
|
第一个有效的 Locator,如果没有则返回 None
|
||||||
|
"""
|
||||||
|
print(f"\n尝试 {len(selectors)} 个定位方式...")
|
||||||
|
print("-" * 50)
|
||||||
|
|
||||||
|
for i, selector in enumerate(selectors):
|
||||||
|
print(f"[{i + 1}] 尝试: {selector}")
|
||||||
|
try:
|
||||||
|
locator = frame.locator(selector)
|
||||||
|
count = locator.count()
|
||||||
|
visible_count = sum(1 for j in range(count) if locator.nth(j).is_visible(timeout=1000))
|
||||||
|
|
||||||
|
print(f" 找到 {count} 个元素,其中 {visible_count} 个可见")
|
||||||
|
|
||||||
|
if visible_count > 0:
|
||||||
|
print(f" ✓ 使用此定位器")
|
||||||
|
print("-" * 50)
|
||||||
|
return locator
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ✗ 失败: {e}")
|
||||||
|
|
||||||
|
print("-" * 50)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def interactive_locate(frame: Frame):
|
||||||
|
"""
|
||||||
|
交互式定位调试 - 进入交互模式测试定位表达式
|
||||||
|
"""
|
||||||
|
print("\n进入交互式定位调试模式")
|
||||||
|
print("输入定位表达式,输入 'q' 或 'quit' 退出")
|
||||||
|
print("-" * 50)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
selector = input("\n>>> ")
|
||||||
|
selector = selector.strip()
|
||||||
|
|
||||||
|
if selector.lower() in ('q', 'quit'):
|
||||||
|
break
|
||||||
|
|
||||||
|
if not selector:
|
||||||
|
continue
|
||||||
|
|
||||||
|
debug_locator(frame, frame.locator(selector))
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
print(f"错误: {e}")
|
||||||
|
|
||||||
|
print("退出调试模式")
|
||||||
|
|
||||||
|
|
||||||
|
# 示例使用代码(单独运行此文件时的演示)
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from playwright.sync_api import sync_playwright
|
||||||
|
import re
|
||||||
|
|
||||||
|
with sync_playwright() as pw:
|
||||||
|
browser = pw.chromium.launch(headless=False)
|
||||||
|
context = browser.new_context(ignore_https_errors=True)
|
||||||
|
page = context.new_page()
|
||||||
|
|
||||||
|
# 登录
|
||||||
|
page.goto("https://68.11.34.30:8082/yonbip/resources/uap/rbac/login/main/index.html")
|
||||||
|
main_frame = page.locator("#forwardFrame").content_frame
|
||||||
|
main_frame.get_by_role("textbox", name="用户名").fill("BLDpengqiangqiang")
|
||||||
|
main_frame.get_by_role("textbox", name="密码").fill("Cqbld123456.")
|
||||||
|
main_frame.get_by_role("button", name="登录").click()
|
||||||
|
confirm_btn = main_frame.get_by_role("button", name="确定")
|
||||||
|
if confirm_btn.count() > 0:
|
||||||
|
confirm_btn.click()
|
||||||
|
|
||||||
|
# 循环切换 Inspector 和交互式调试
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("元素定位调试工具")
|
||||||
|
print("=" * 60)
|
||||||
|
print("循环模式:")
|
||||||
|
print(" 1. Inspector 窗口 - 使用浏览器录制/选择元素")
|
||||||
|
print(" 2. 交互式调试 - 验证定位表达式")
|
||||||
|
print(" 输入 'q' 或 'quit' 退出程序\n")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# 1. 打开 Inspector 窗口
|
||||||
|
print("\n【打开 Inspector 窗口】")
|
||||||
|
print("请在 Inspector 中获取元素定位器,然后关闭 Inspector 继续...")
|
||||||
|
page.pause()
|
||||||
|
|
||||||
|
# 2. 进入交互式定位调试
|
||||||
|
print("\n【进入交互式定位调试】")
|
||||||
|
interactive_locate(main_frame)
|
||||||
|
|
||||||
|
# 询问是否继续
|
||||||
|
choice = input("\n是否继续下一轮调试?(y/n/q): ").strip().lower()
|
||||||
|
if choice in ('n', 'q', 'quit'):
|
||||||
|
print("退出程序")
|
||||||
|
break
|
||||||
|
elif choice in ('y', ''): # 默认继续
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
print("未知选项,退出程序")
|
||||||
|
break
|
||||||
|
|
||||||
|
context.close()
|
||||||
|
browser.close()
|
||||||
55
main.py
55
main.py
@@ -3,7 +3,9 @@
|
|||||||
"""
|
"""
|
||||||
from playwright.sync_api import sync_playwright
|
from playwright.sync_api import sync_playwright
|
||||||
from login import login
|
from login import login
|
||||||
|
from time import sleep
|
||||||
|
import re
|
||||||
|
import time
|
||||||
def main():
|
def main():
|
||||||
with sync_playwright() as playwright:
|
with sync_playwright() as playwright:
|
||||||
# 调用登录模块
|
# 调用登录模块
|
||||||
@@ -16,8 +18,57 @@ def main():
|
|||||||
)
|
)
|
||||||
|
|
||||||
# 登录成功后可以进行后续操作
|
# 登录成功后可以进行后续操作
|
||||||
print("登录成功,可以进行后续操作...")
|
# 点击打开“菜单”
|
||||||
|
main_frame.locator("i").first.click()
|
||||||
|
#page.pause()
|
||||||
|
# 点击打开“菜单”
|
||||||
|
with page.expect_popup() as page1_info:
|
||||||
|
main_frame.get_by_title("离散备料计划维护", exact=True).first.click()
|
||||||
|
page1 = page1_info.value
|
||||||
|
|
||||||
|
|
||||||
|
main_frame=page1.locator("#forwardFrame").content_frame
|
||||||
|
inner_frame_locator = main_frame.locator("#mainiframe")
|
||||||
|
inner_frame_locator.wait_for(state="visible", timeout=15000)
|
||||||
|
inner_frame = inner_frame_locator.content_frame
|
||||||
|
|
||||||
|
# 点击图标按钮
|
||||||
|
inner_frame.locator(".search-name-wrapper > .iconfont").click()
|
||||||
|
inner_frame.get_by_text("订单号查询").click()
|
||||||
|
textbox = inner_frame.get_by_role("textbox", name="来源生产订单号")
|
||||||
|
textbox.fill("SC70202510110003,SC70202510110004")
|
||||||
|
inner_frame.get_by_role("tab", name="全部").click()
|
||||||
|
inner_frame.locator("#rc_select_0").fill("5000")
|
||||||
|
#发送回车键
|
||||||
|
inner_frame.locator("#rc_select_0").press("Enter")
|
||||||
|
inner_frame.locator(".search-component-searchBtn").click()
|
||||||
|
print("查询完成,等待加载结果...")
|
||||||
|
# 等待加载完成
|
||||||
|
loading_locator = inner_frame.locator("div").filter(has_text="加载中").nth(1)
|
||||||
|
try:
|
||||||
|
loading_locator.wait_for(state="visible", timeout=3000)
|
||||||
|
loading_locator.wait_for(state="hidden", timeout=0) # 无限等待,直到消失
|
||||||
|
except TimeoutError:
|
||||||
|
# 加载很快完成,或者没有出现加载提示
|
||||||
|
pass
|
||||||
|
print("加载完成,开始选择数据...")
|
||||||
|
inner_frame.get_by_role("row", name="序号").get_by_label("").check()
|
||||||
|
|
||||||
|
inner_frame.get_by_role("button", name="更多").hover()
|
||||||
|
inner_frame.get_by_text("输出").click()
|
||||||
|
input_box = inner_frame.locator("div").filter(has_text=re.compile(r"^行数阈值$")).locator("input[type='text']")
|
||||||
|
input_box.fill("300000")
|
||||||
|
# 等待下载事件
|
||||||
|
with page1.expect_download() as download_info:
|
||||||
|
inner_frame.get_by_role("button", name="确定(Y)").click()
|
||||||
|
|
||||||
|
# 获取下载对象
|
||||||
|
download = download_info.value
|
||||||
|
|
||||||
|
# 指定保存路径和文件名
|
||||||
|
download.save_as("D:/python/playwrite/data/导出文件.xlsx")
|
||||||
|
|
||||||
|
page1.pause()
|
||||||
input("按回车退出...")
|
input("按回车退出...")
|
||||||
|
|
||||||
# 关闭浏览器
|
# 关闭浏览器
|
||||||
|
|||||||
Reference in New Issue
Block a user