手搓全自动文章多平台发布系统: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。准备给下一个任务使用。计划每次只发布一个网站,如果要一个站点多次发布的。则需要循环即可。或不关闭等待下一次的使用。但不科学,万一有上百个要发布的,会卡的。另外还需要使用小型数据库进行管理。

相关推荐
bemyrunningdog7 分钟前
Mock数据
linux·运维·ubuntu
周胡杰17 分钟前
鸿蒙arkts使用关系型数据库,使用DB Browser for SQLite连接和查看数据库数据?使用TaskPool进行频繁数据库操作
前端·数据库·华为·harmonyos·鸿蒙·鸿蒙系统
wkj00120 分钟前
navicate如何设置数据库引擎
数据库·mysql
赵渝强老师23 分钟前
【赵渝强老师】Oracle RMAN的目录数据库
数据库·oracle
暖暖木头25 分钟前
Oracle注释详解
数据库·oracle
御控工业物联网42 分钟前
御控网关如何实现MQTT、MODBUS、OPCUA、SQL、HTTP之间协议转换
数据库·sql·http
PHOSKEY1 小时前
闪测仪应用案例丨手机中框如何突破「尺寸检测」瓶颈?
运维·智能手机·自动化
JIAKSK2 小时前
VitePress 接入百度统计:全面教程与优化指南
运维·数据可视化
网硕互联的小客服2 小时前
未来趋势:AI与量子计算对服务器安全的影响
运维·服务器·网络·网络安全·量子计算
GJCTYU2 小时前
spring中@Transactional注解和事务的实战理解附代码
数据库·spring boot·后端·spring·oracle·mybatis