将网页操作的脚本自动保存成yaml ,然后修改使用

devtools/2025/4/1 5:21:37/

可以使用 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 工具。


http://www.ppmy.cn/devtools/172201.html

相关文章

安装Webpack并创建vue项目

1、新建一个工程目录 在E盘中进行新建项目 2、从命令行进入该目录,并执行NPM 的初始化命令 3、会看到目录中生成了一个“package.json”文件,它相当于NPM项目的说明书,里面记录了项目名称、版本、仓库地址等信息。 4、执行安装 Webpack 的命令 npm install webpac…

鸿蒙OS 5.0 服务能力框架深入剖析

鸿蒙OS 5.0 服务能力框架中关键类的作用分析 1\. 鸿蒙OS 5.0 服务能力框架导论 鸿蒙OS 5.0,亦称鸿蒙智联 5 1,标志着华为在分布式操作系统领域迈出的重要一步。与早期版本采用兼容安卓的AOSP层、Linux内核以及LiteOS内核不同,鸿蒙OS 5.0 专注…

如何快速看懂并修改神经网络

前言:个人之见,一个神经网络网络源码出现,你先看数据集的输入和输出,而这数据集肯定要包括数据增加和制作数据集,第二 看模型的输入和输出(至于模型内部可以自己看论文 无非就是加了几个组件),然…

deepseek(2)——deepseek 关键技术

1 Multi-Head Latent Attention (MLA) MLA的核心在于通过低秩联合压缩来减少注意力键(keys)和值(values)在推理过程中的缓存,从而提高推理效率: c t K V W D K V h t c_t^{KV} W^{DKV}h_t ctKV​WDKVht​…

Java制作简单的聊天室(复习)

设计的知识点:几乎包含java基础的全部知识点(java基础语法,java基础进阶:双列集合,io流,多线程,网络编程等) 代码如下 客户端: 服务器采用的时多线程的循环多线程的方式…

Wireshark网络抓包分析使用详解

序言 之前学计网还有前几天备考华为 ICT 网络赛道时都有了解认识 Wireshark,但一直没怎么专门去用过,也没去系统学习过,就想趁着备考的网络相关知识还没忘光,先来系统学下整理点笔记~ 什么是抓包?抓包就是将网络传输…

C语言基础—构造类型

数据类型 1.基本类型/基础类型 整型 短整型:short[int] --2字节 基本整型:int --4字节 长整型:long[int] --32位4字节/64位8字节 长长整型:long long [int] (C99) 注意:以上类型又都分为sig…

爬虫学习-爬取古诗

目录 流程讲解以及代码构建 1. get_html 函数 2. get_poem_data 函数 3. get_poem_links_by_type 函数 4. get_data 函数 5. save_data 函数 6. analyze_data 函数 7. visualize_data 函数 主程序逻辑 运行效果 完整代码 古诗网址:唐诗三百首全集_古诗文网 唐诗作为…