你可以通过结合 Selenium 和自定义 JavaScript 监听事件来实现交互式元素捕获,并将操作保存到 YAML 文件。以下是分步实现方案:
---
### **1. 技术栈选择**
- **Selenium**:用于操控浏览器
- **PyYAML**:用于读写 YAML 文件
- **JavaScript 注入**:实现网页内的右键菜单和元素捕获
---
### **2. 实现步骤**
#### **2.1 注入 JavaScript 监听事件**
在页面加载后注入 JS 代码,监听鼠标悬停和右键点击事件,生成元素高亮和自定义右键菜单。
```python
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://example.com")
# 注入 JavaScript 代码
js_script = """
// 高亮元素样式
const style = document.createElement('style');
style.innerHTML = '.hover-highlight { outline: 2px solid red !important; }';
document.head.appendChild(style);
// 鼠标悬停高亮
document.addEventListener('mouseover', (e) => {
if (window.elementHighlight) window.elementHighlight.classList.remove('hover-highlight');
e.target.classList.add('hover-highlight');
window.elementHighlight = e.target;
});
// 右键菜单
document.addEventListener('contextmenu', (e) => {
e.preventDefault();
window.selectedElement = e.target;
// 创建菜单
const menu = document.createElement('div');
menu.innerHTML = `
`;
menu.id = 'custom-menu';
document.body.appendChild(menu);
});
// 处理菜单点击
window.handleMenuClick = (actionType) => {
const element = window.selectedElement;
const xpath = getXPath(element); // 获取元素的 XPath
document.getElementById('custom-menu').remove();
// 将数据存储到隐藏的输入框
const data = JSON.stringify({ action: actionType, xpath: xpath });
document.getElementById('selenium-data').value = data;
};
// 获取元素的 XPath
function getXPath(element) {
if (element.id !== '') return '//*[@id="' + element.id + '"]';
if (element === document.body) return '/html/body';
let ix = 0;
const siblings = element.parentNode.childNodes;
for (let i = 0; i < siblings.length; i++) {
const sibling = siblings[i];
if (sibling === element) return getXPath(element.parentNode) + '/' + element.tagName.toLowerCase() + '[' + (ix + 1) + ']';
if (sibling.nodeType === 1 && sibling.tagName === element.tagName) ix++;
}
}
"""
driver.execute_script(js_script)
# 创建隐藏输入框用于传递数据
driver.execute_script('document.body.innerHTML += ""')
```
---
#### **2.2 捕获用户操作并保存到 YAML**
监听隐藏输入框的值变化,当用户通过右键菜单选择操作后获取数据。
```python
import yaml
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
actions = []
while True:
try:
# 等待用户操作(最长等待10秒)
data_str = WebDriverWait(driver, 10).until(
lambda d: d.find_element(By.ID, "selenium-data").get_attribute("value") or False
)
if data_str:
action_data = json.loads(data_str)
print(f"捕获操作:{action_data}")
actions.append(action_data)
# 清空输入框以准备下一次操作
driver.execute_script('document.getElementById("selenium-data").value = ""')
# 提示用户是否继续
choice = input("是否继续捕获?(y/n): ")
if choice.lower() != 'y':
break
except:
break
# 保存到 YAML 文件
with open('actions.yaml', 'w') as f:
yaml.dump(actions, f)
driver.quit()
```
---
#### **2.3 回放 YAML 中的操作**
读取 YAML 文件并使用 Selenium 自动执行。
```python
with open('actions.yaml', 'r') as f:
actions = yaml.safe_load(f)
driver = webdriver.Chrome()
driver.get("https://example.com")
for action in actions:
element = driver.find_element(By.XPATH, action['xpath'])
if action['action'] == 'click':
element.click()
elif action['action'] == 'input':
element.send_keys("Hello World")
driver.quit()
```
---
### **3. 功能扩展建议**
1. **元素定位优化**:支持 CSS 选择器、ID 等多种定位方式。
2. **参数化输入**:允许用户在 YAML 中指定输入内容。
3. **步骤延迟**:添加等待时间确保元素加载完成。
4. **错误处理**:捕获异常并生成日志。
---
### **4. 完整项目结构**
```
- main.py # 主程序(捕获和回放)
- actions.yaml # 存储操作步骤
- utils/
- element_recorder.py # 元素捕获逻辑
- executor.py # 回放逻辑
```
通过此方案,你可以交互式捕获网页操作并实现自动化回放,适合构建简单的自动化测试工具或爬虫流程。