手搓全自动文章多平台发布系统:8、自动化脚本的测试。

今天课太多,一直没时间搞。下午利用一点时间进行了测试与整合,以头条发布为例。形成了通用的脚本模型及处理代码部分。目前已经能成功发布。其他平台没测试。看来得下一周再继续了,周五了。

yaml部分关于测试的部分。注意在文本方面输入有两种:一种是fill 一种是type.另外输入框获取焦点的方式,是在F12测试时,观察其如class闪动的地方,进行点击即可得到焦点。然后进行内容的type.

复制代码
  - name: 头条
    url: https://www.toutiao.com/
    cookies_path: cookies/toutiao
    login_identifier: ".user-list.ttp-popup-container"  # 头条登录后的用户账户链接选择器
    url_pattern: https://mp.toutiao.com/profile_v4/graphic/publish  # 匹配头条的文章发布页面
    auto_actions:
      - type: click
        selector: ".close-btn"  # 关闭弹窗
        timeout: 10000
#      - type: click
#        selector: textarea[placeholder="请输入文章标题(2~30个字)"]
#        timeout: 10000
      - type: fill  # 填充标题
        selector: textarea[placeholder="请输入文章标题(2~30个字)"]
        content: "我是测试标题"
        options:
          delay: 1000

      - type: wait
        timeout: 500  # 等待5秒
      - type: click   # 点击编辑器
        selector: ".ProseMirror"
        timeout: 10000
      - type: type  # 输入内容
        selector: "span.syl-placeholder.ProseMirror-widget[ignoreel='true']"
        content: "我是测试内容"
        options:
          delay: 1000

      - type: click  # 点击第三个选项
        selector: "div.byte-radio-group label:nth-of-type(3)"
        timeout: 500  # 等待5秒

      - type: click  # 点击作品声明
        selector: "div.source-info-wrap label:nth-of-type(3)"
        timeout: 500  # 等待5秒

      - type: click  # 点击预览
        selector: "div.garr-footer-publish-content button:nth-of-type(1)"
        timeout: 10000

      - type: click  # 点击发布
        selector: "div.garr-footer-publish-content button:nth-of-type(3)"
        timeout: 10000

关键代码,还可以扩充上传文件,视频等内容。目前因用不到所以没有进行测试。

复制代码
    async def perform_actions(self,page, actions):
        """执行自动化操作序列"""
        for action in actions:
            try:
                action_type = action.get("type")
                if action_type == "fill":
                    await self.handle_fill(page, action)
                elif action_type == "click":
                    await self.handle_click(page, action)
                elif action_type == "wait":
                    await self.handle_wait(action)
                elif action_type == "type":
                    await self.handle_type(page,action)
                else:
                    print(f"未实现的动作类型: {action_type}")
            except Exception as e:
                print(f"执行动作失败: {action},错误: {e}")

    async def handle_click(self,page, action):
        """处理点击操作"""
        selector = action["selector"]
        timeout = action.get("timeout", 5000)

        # 等待元素可点击
        await page.wait_for_selector(selector, state="visible", timeout=timeout)
        await page.click(selector)
        print(f"点击元素 {selector}")

    async def handle_fill(self,page, action):
        """处理填充操作"""
        selector = action["selector"]
        content = action["content"]
        options = action.get("options", {})

        # 等待元素出现
        await page.wait_for_selector(selector, timeout=action.get("timeout", 5000))

        # 使用 fill 方法
        await page.fill(selector, content)
        print(f"填充字段 {selector} 为 {content}")

        # 处理 delay 选项
        delay = options.get("delay", 0)
        if delay:
            await page.keyboard.type("", delay=delay)  # 通过空输入模拟延迟

    async def handle_type(self,page, action):
        """处理填充操作"""
        selector = action["selector"]
        content = action["content"]
        options = action.get("options", {})

        # 等待元素出现
        await page.wait_for_selector(selector, timeout=action.get("timeout", 5000))

        # 使用 fill 方法
        await page.type(selector, content)
        print(f"填充字段 {selector} 为 {content}")

        # 处理 delay 选项
        delay = options.get("delay", 0)
        if delay:
            await page.keyboard.type("", delay=delay)  # 通过空输入模拟延迟

最关键的函数,对自动化的部分进行了修改。

复制代码
async def browser_main(idx: int, auto: bool = False, headless=False):
    manager = BrowserManager()
    max_retries = 3
    for retry in range(max_retries):
        try:
            if manager._context_closed:
                await manager.close_all()
                await manager.initialize(headless=headless)

            config = ConfigManager()
            page = await manager.get_page(idx,auto=auto)
            if auto:
                url = config.get_url_pattern(idx)
                print(f"自动工作模式开启,使用URL模式:{url}")
                await page.goto(url, wait_until="load")
                # 新增:执行自动化操作
                auto_actions = config.get_auto_actions(idx)
                await manager.perform_actions(page, auto_actions)  # 调用模块化函数
            else:
                url = config.get_site_url(idx)

                login_selector = config.get_login_identifier(idx)
                await page.goto(url, wait_until="load")
                print(f"手动模式开始,使用URL:{url}")

            print(f"当前页面索引:", list(manager._pages.keys()))

            # 检测登录状态
            if not auto:
                logged_in = await manager.is_logged_in(page, login_selector)
                return (idx, logged_in)
            break
        except Exception as e:
            if retry < max_retries - 1:
                print(f"任务执行失败,重试第 {retry + 1} 次: {e}")
                manager._context_closed = True
            else:
                print(f"任务执行失败,已达到最大重试次数: {e}")

其他部分无修改。下一步需要进一步加工的部分在于外部文件的导入。完成后自动关闭当面page。准备给下一个任务使用。计划每次只发布一个网站,如果要一个站点多次发布的。则需要循环即可。或不关闭等待下一次的使用。但不科学,万一有上百个要发布的,会卡的。另外还需要使用小型数据库进行管理。

相关推荐
qq_12498707535 分钟前
基于JavaWeb的大学生房屋租赁系统(源码+论文+部署+安装)
java·数据库·人工智能·spring boot·计算机视觉·毕业设计·计算机毕业设计
消失的旧时光-19438 分钟前
Linux 入门核心命令清单(工程版)
linux·运维·服务器
艾莉丝努力练剑16 分钟前
【Linux:文件】Ext系列文件系统(初阶)
大数据·linux·运维·服务器·c++·人工智能·算法
小天源19 分钟前
Cacti在Debian/Ubuntu中安装及其使用
运维·ubuntu·debian·cacti
梦帮科技29 分钟前
OpenClaw 桥接调用 Windows MCP:打造你的 AI 桌面自动化助手
人工智能·windows·自动化
倒流时光三十年37 分钟前
SpringBoot 数据库同步 Elasticsearch 性能优化
数据库·spring boot·elasticsearch
Trouvaille ~42 分钟前
【Linux】TCP Socket编程实战(一):API详解与单连接Echo Server
linux·运维·服务器·网络·c++·tcp/ip·socket
芷栀夏1 小时前
深度解析 CANN 异构计算架构:基于 ACL API 的算子调用实战
运维·人工智能·开源·cann
feasibility.1 小时前
AI 编程助手进阶指南:从 Claude Code 到 OpenCode 的工程化经验总结
人工智能·经验分享·设计模式·自动化·agi·skills·opencode
全栈工程师修炼指南1 小时前
Nginx | stream 四层反向代理:SSL、PREREAD 阶段模块指令浅析与实践
运维·网络·网络协议·nginx·ssl