将网页操作的脚本自动保存成yaml ,然后修改使用
可以使用 Playwright 更优雅地实现你的需求,它相比 Selenium 具有更现代化的 API 和更好的浏览器控制能力。以下是基于 Playwright 的改进方案:
---
### **1. Playwright 核心优势**
- **内置自动等待**:无需手动处理元素加载等待
- **多浏览器支持**:Chromium/Firefox/WebKit 统一 API
- **强大的录制功能**:自带 `codegen` 模式可生成操作代码
- **现代化选择器引擎**:支持 CSS/XPath/文本/角色等多种定位方式
---
### **2. 改进后方案设计**
#### **2.1 录制系统架构**
```python
from playwright.sync_api import sync_playwright
import yaml
class ActionRecorder:
def __init__(self):
self.actions = []
self.playwright = sync_playwright().start()
self.browser = self.playwright.chromium.launch(headless=False)
self.context = self.browser.new_context()
self.page = self.context.new_page()
def start_recording(self, url):
self.page.goto(url)
# 注入元素选择检测
self.page.expose_function("onElementSelected", self.handle_element_selected)
self.page.add_script_tag(content="""
document.addEventListener('click', async (e) => {
e.preventDefault();
const target = e.target;
const selectors = {
css: target.cssSelector,
xpath: target.xpathSelector,
text: target.innerText.trim().slice(0,20),
id: target.id ? `#${target.id}` : null
};
await window.onElementSelected(selectors);
});
""")
def handle_element_selected(self, selectors):
# 弹出选择器选择对话框(伪代码)
chosen_selector = self.show_selector_dialog(selectors)
self.actions.append({
"type": "click",
"selectors": [chosen_selector],
"timeout": 10000
})
def save_to_yaml(self, filename):
with open(filename, 'w') as f:
yaml.dump({"auto_actions": self.actions}, f)
```
---
### **3. 关键功能实现**
#### **3.1 多选择器支持与验证**
```python
class SelectorEngine:
@staticmethod
def find_element(page, selectors):
"""尝试多种选择器直到找到元素"""
for selector in selectors:
try:
return page.locator(selector).first
except:
continue
raise Exception("No valid selector found")
@staticmethod
def highlight_element(page, selector):
"""测试选择器有效性"""
try:
locator = page.locator(selector)
locator.evaluate("elem => elem.style.outline = '3px solid red'")
return True
except:
return False
```
---
#### **3.2 完整操作配置示例**
```yaml
- name: 头条自动化
url: https://www.toutiao.com/
actions:
- type: navigate
url: https://mp.toutiao.com/profile_v4/graphic/publish
- type: click
selectors:
- ".close-btn" # 首选CSS
- "//button[contains(@class, 'close-btn')]" # 备用XPath
timeout: 10000
- type: fill
selectors:
- "textarea[placeholder='请输入文章标题']"
content: "我是测试标题"
options:
delay: 1000
- type: keyboard
key: "Tab" # 支持键盘操作
- type: upload
selector: "input[type=file]"
files: ["cover.jpg"]
```
---
### **4. GUI 集成方案(PyQt6 + Playwright)**
#### **4.1 浏览器组件集成**
```python
from PyQt6.QtWidgets import QApplication, QMainWindow
from PyQt6.QtCore import QUrl
from playwright.sync_api import sync_playwright
class BrowserWindow(QMainWindow):
def __init__(self):
super().__init__()
self.playwright = sync_playwright().start()
self.browser = self.playwright.chromium.launch(headless=False)
self.context = self.browser.new_context()
self.page = self.context.new_page()
# 创建浏览器视图容器
self.container = QWidget(self)
self.setCentralWidget(self.container)
# 将 Playwright 页面绑定到窗口
self.page.goto("https://example.com")
def closeEvent(self, event):
self.context.close()
self.browser.close()
self.playwright.stop()
```
---
#### **4.2 带测试按钮的配置界面**
```python
class ActionConfigurator(QWidget):
def __init__(self, page):
super().__init__()
self.page = page
self.init_ui()
def init_ui(self):
# 选择器输入框
self.selector_input = QLineEdit()
# 测试按钮
test_btn = QPushButton("测试选择器")
test_btn.clicked.connect(self.test_selector)
# 结果显示
self.result_label = QLabel()
def test_selector(self):
selector = self.selector_input.text()
valid = SelectorEngine.highlight_element(self.page, selector)
self.result_label.setText(f"选择器状态: {'有效' if valid else '无效'}")
```
---
### **5. 执行引擎实现**
```python
class ActionExecutor:
def __init__(self, config_path):
with open(config_path) as f:
self.config = yaml.safe_load(f)
self.playwright = sync_playwright().start()
self.browser = self.playwright.chromium.launch(headless=False)
self.context = self.browser.new_context()
self.page = self.context.new_page()
def run(self):
self.page.goto(self.config['url'])
for action in self.config['actions']:
self.execute_action(action)
def execute_action(self, action):
element = SelectorEngine.find_element(
self.page,
action['selectors']
)
if action['type'] == 'click':
element.click(timeout=action.get('timeout', 30000))
elif action['type'] == 'fill':
element.fill(action['content'])
elif action['type'] == 'upload':
element.set_input_files(action['files'])
```
---
### **6. 优势对比**
| 功能 | Selenium 方案 | Playwright 改进方案 |
|---------------------|-------------------------|-----------------------------|
| 元素等待机制 | 需要显式等待 | 内置智能等待 |
| 浏览器支持 | 需单独驱动 | 内置三大浏览器 |
| 录制功能 | 需自定义实现 | 自带 codegen 录制模式 |
| 执行速度 | 较慢 | 快 30%+ |
| 选择器引擎 | 基础 CSS/XPath | 支持角色/文本等高级定位 |
| 文件上传 | 复杂 | 直接 set_input_files |
---
### **7. 部署使用**
1. **安装依赖**:
```bash
pip install playwright pyqt6 pyyaml
playwright install chromium
```
2. **启动录制**:
```python
recorder = ActionRecorder()
recorder.start_recording("https://www.toutiao.com")
# 进行页面操作...
recorder.save_to_yaml("toutiao_actions.yaml")
```
3. **执行自动化**:
```python
executor = ActionExecutor("toutiao_actions.yaml")
executor.run()
```
---
这种方案结合了:
- Playwright 的现代化浏览器控制能力
- PyQt6 的 GUI 交互界面
- 智能选择器验证系统
- 多选择器容错机制
- YAML 配置的易读性
可以通过扩展 `Action` 类型来支持更多操作(如拖放、滚动等),适合构建企业级自动化测试平台或 RPA 工具。