前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >工具分享 | 自动化填写腾讯云获奖表单

工具分享 | 自动化填写腾讯云获奖表单

原创
作者头像
叫我阿柒啊
发布2025-01-21 14:28:07
发布2025-01-21 14:28:07
32200
代码可运行
举报
运行总次数:0
代码可运行

前言

最近腾讯云开发者社区的活动越来越多,很多优秀的开发者也经常收到小助理邀请填写中奖收货地址的消息。最近在社区普天同庆的年终活动中,我也是有幸获得了几个可爱周边,所以也遇到了每次都要手敲电话号码、收货信息的问题。

所以在空闲之余,就用 Python + PyQt6 开发了一个腾讯云获奖表单自动填写的桌面工具。这个工具可以帮助用户快速填写重复的表单信息,支持地址信息的保存和管理。

演示效果:

项目介绍

本程序github地址:腾讯云获奖表单自动填写工具

git clone下来之后,运行 form_filler.py 主程序即可。form_template.html是表单填写页面,可以使用这个页面测试。

需求分析

这是我当前收集到的两个表单,结构如下:

针对于上面的这个表单,我们通过开发者工具查看HTML元素。

可以看到每个input的class属性都是一样的,而name属性都是唯一的字符,所以这里就可以考虑使用name属性来定位元素。为了避免不同的名单中的name是随机的,所以我又找了一个表单去验证。

这个表单多了一个微信的输入框,这个暂且不管,同样查看HTML。

我们可以看到这个表单的name与上面的表单是相同的。目前没有第三个表单进行验证,如果后续name属性变动的话,就要考虑使用input的顺序和一些其他的元素辅助定位。这里先不考虑这么多,就用name定位。

技术架构

说到自动化工具,我们自然而然就想到了selenium,加上填写表单之前需要使用微信扫码登录,所以使用selenium无疑是最好的选择。

GUI框架使用的是 PyQt6。相比Tkinter更现代的界面,刚开始我使用Tkinter进行的开发,但是遇到了输入框双击无法编辑、按钮点击无响应等问题,最终放弃使用PyQt6。

最后使用pyinstaller工具,将python打包成exe等PC可运行的桌面应用。

程序开发

程序的模块主要后台逻辑、GUI页面设计、 个人信息管理、程序打包四个部分。

后台逻辑

后台逻辑这一块主要是实现打开浏览器自动填写页面的功能,以及其中包含的一些细节。

1. 表单填写

我们使用selenium来打开一个浏览器,然后完成扫码登录、页面填写的动作。所以我们要确保已安装Chrome浏览器

代码语言:python
代码运行次数:0
复制
from selenium import webdriver

def __init__(self):
  try:
      self.driver = webdriver.Chrome()
  except Exception as e:
      raise Exception(f"无法启动Chrome浏览器: {str(e)}"

表单自动填写就是通过selenium来定位表单的元素,然后将定义的数据变量回填到表单中。主要逻辑代码如下:

代码语言:python
代码运行次数:0
复制
def fill_form(self, url, form_data):
  try:
      self.driver.get(url)
      wait = WebDriverWait(self.driver, 10)

      # 等待并填写昵称
      nickname_input = wait.until(
          EC.presence_of_element_located((By.NAME, "7lap1mcqwr7"))
      )
      nickname_input.send_keys(form_data['nickname'])

      # 填写其他字段
      name_input = self.driver.find_element(By.NAME, "xepe2botxth")
      name_input.send_keys(form_data['name'])

      phone_input = self.driver.find_element(By.NAME, "tvvoz8pt5tf")
      phone_input.send_keys(form_data['phone'])

      address_input = self.driver.find_element(By.NAME, "f54spd7ug5q")
      address_input.send_keys(form_data['address'])

EC 是 expected_conditions 的缩写,它是 Selenium 中的一个重要模块,用于定义期望的条件,主要用于显式等待(explicit wait)场景,我们在代码中引入EC。

代码语言:python
代码运行次数:0
复制
from selenium.webdriver.support import expected_conditions as EC

在代码中,我们使用EC来等待直到找到 name="7lap1mcqwr7" 的元素出现在DOM中,如果在超时时间内找到了元素,返回该元素。如果超时还没找到,意味着当前表单不符合程序内要填写的表单结构,所以抛出异常。

2. 点击事件

这里的点击事件,包括勾选复选框同意协议,然后点击提交。后来我把提交按钮的代码注释掉了,原因就是我在测试功能的时候,使用了正式的获奖表单链接,导致我的收货地址填的都是错误的测试数据,但是表单填完之后没法修改,最后只能辛苦小助理添加了备注。

勾选复选框的代码如下:

代码语言:python
代码运行次数:0
复制
# 勾选协议复选框
checkbox = self.driver.find_element(By.CLASS_NAME, "f-checkbox")
if not checkbox.is_selected():
    checkbox.click()
                

GUI页面设计

GUI的设计主要使用 PyQt6 完成的,最初使用的 Tkinter,在开发完成之后发现交互性体验感不太好,所以就换成了 PyQt6。

1. 主窗口布局

主窗口设计就是一个简单的布局,提供了查看和修改地址的按钮入口,用户在输入获奖的表单URL之后,点击开始填写按钮就会在浏览器打开表单,然后完成自动化填写。

GUI在样式上确实没有H5页面那么丰富,但是我们可以使用一些简单设置。为了让表单在任何尺寸的终端都能保持不变形,这里使用了setFixedSize为窗口设置了固定尺寸。布局方面使用了QVBoxLayout垂直布局,并设置了适当的间距和边距,这样可以让界面元素分布更加合理。

代码语言:python
代码运行次数:0
复制
def setup_ui(self):
    self.setWindowTitle("腾讯云表单自动填写工具")
    self.setFixedSize(500, 300)
    
    central_widget = QWidget()
    self.setCentralWidget(central_widget)
    layout = QVBoxLayout(central_widget)
    layout.setSpacing(20)
    layout.setContentsMargins(20, 20, 20, 20)

最终窗口样式如下:

2. 按钮设计

其实按钮的设计比较简单,这里是是一共三个按钮。查看地址按钮就是查看维护的个人信息。

通过修改按钮出发弹窗,可以在里面修改个人信息。

3. 电话号码验证

在修改个人信息页面中,增加了电话号码格式的验证:

代码语言:python
代码运行次数:0
复制
def validate_phone(self, text):
    """验证电话号码格式"""
    text = ''.join(filter(str.isdigit, text))
    is_valid = len(text) == 11 and text.startswith(('13', '14', '15', '16', '17', '18', '19'))
    
    if text:
        if is_valid:
            phone_entry.setStyleSheet("border: 1px solid #52c41a;")
        else:
            phone_entry.setStyleSheet("border: 1px solid #ff4d4f;")

电话号码验证自动过滤非数字字符,提升用户体验,实时验证号码格式,立即提供反馈,以及使用绿色和红色边框直观显示验证结果。

个人信息管理

这个桌面工具主要是为了自动填写个人信息,所以需要实现维护个人信息的功能。在一个PC首次使用这个工具的时候,就会弹出提示框强制你修改个人信息。

点击OK之后,就会跳转到个人信息修改页面。

修改之后点击保存即可。在这个功能实现中,我们只需要考虑一个问题:如何判断是首次使用? 首次使用功能主要通过比较当前配置与默认配置来判断,如果完全一致则认为是首次使用。实现包含以下几个关键部分:

1. 默认配置定义

config.py 中定义默认个人信息配置:

代码语言:python
代码运行次数:0
复制
DEFAULT_FORM_DATA = {
    'nickname': '测试昵称',
    'name': '张三',
    'phone': '13800138000',
    'address': '广东省深圳市南山区腾讯大厦'
}

这个就是一个模板,在这里可以修改为空,但是不要修改成你的实际收货地址,因为需要用这个文件判断是否首次使用,所以不能和你的实际信息一致。

2. 配置管理

config_manager.py 中实现配置的加载和保存:

代码语言:python
代码运行次数:0
复制
def load_config():
    # 加载配置文件
    try:
        with open('form_config.json', 'r', encoding='utf-8') as f:
            return json.load(f)
    except FileNotFoundError:
        return DEFAULT_FORM_DATA.copy()

def save_config(config):
    # 保存配置到文件
    with open('form_config.json', 'w', encoding='utf-8') as f:
        json.dump(config, f, ensure_ascii=False, indent=2)

代码主要实现了form_config.json 的加载,在原始的程序目录中是没有这个文件的,所以load_config的逻辑是默认从DEFAULT_FORM_DATA复制。

3. 首次使用检测

check_first_run 方法中实现首次使用检测:

代码语言:python
代码运行次数:0
复制
def check_first_run(self):
    # 检查是否使用默认配置
    is_default = all(
        self.form_data[key] == DEFAULT_FORM_DATA[key]
        for key in DEFAULT_FORM_DATA
    )
    
    if is_default:
        # 显示强制修改提示
        QMessageBox.information(
            self,
            "首次使用提示",
            "首次使用请修改收货地址",
            QMessageBox.StandardButton.Ok
        )

is_default 是 form_config.json 与 DEFAULT_FORM_DATA 的数据比较结果,如果为True,表示用户未修改个人信息,所以就是用弹出对话框提示用户修改。

4. 修改检测

但是有的用户真的叛逆(也可能是手滑),在修改之后点击了取消,或者未修改就点击了保存。这就导致用户没把准确的个人信息维护成功,所以在这里增加了修改检测逻辑。

代码语言:python
代码运行次数:0
复制
# 强制打开修改对话框,直到用户修改了地址
while is_default:
    dialog = FormDataDialog(self, self.form_data, readonly=False)
    if dialog.exec():
        self.form_data = dialog.result
        save_config(self.form_data)

        # 检查是否真的修改了
        is_default = all(
            self.form_data[key] == DEFAULT_FORM_DATA[key]
            for key in DEFAULT_FORM_DATA
        )

        if is_default:
            QMessageBox.warning(
                self,
                "提示",
                "请修改默认的收货地址信息!",
                QMessageBox.StandardButton.Ok
            )
    else:
        # 用户点击取消,再次提醒
        reply = QMessageBox.warning(
            self,
            "提示",
            "首次使用必须修改默认地址,是否继续?",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
        )
        if reply == QMessageBox.StandardButton.No:
            sys.exit(0)  # 用户选择退出程序

在修改之后点击了取消,或者未修改就点击了保存后关闭修改页面,就会弹出下面提示框:

5. 功能验证

在修改了个人信息之后,点击保存。

form_config.json 中可以看到个人信息已经被修改。

代码语言:json
复制
{
    "nickname": "叫我阿柒啊",
    "name": "阿柒",
    "phone": "13800138001",
    "address": "广东省深圳市南山区腾讯大厦"
}

程序打包

在完成了自动化表单填写工具的开发后,为了让没有主机的环境我们需要将其打包成可执行文件,方便用户使用。

1. 依赖安装

在开始打包之前,我们需要确保所有依赖都已正确安装。特别是PyInstaller,它是我们主要的打包工具。这里建议使用venv虚拟环境进行打包。

代码语言:bash
复制
# 创建虚拟环境
python -m venv venv_build

# 激活虚拟环境
# Windows:
.\venv_build\Scripts\activate
# macOS/Linux:
source venv_build/bin/activate

# 安装依赖
pip install -r requirements.txt
2. 打包命令

常用的打包命令如下:

代码语言:bash
复制
# 单文件打包(推荐)
pyinstaller --clean --windowed --onefile --name "表单填写工具" form_filler.py

# 添加图标打包
pyinstaller --clean --windowed --onefile --icon=icon.ico --name "表单填写工具" form_filler.py

在这个程序中,建议去掉onefile参数,这样在打包之后运行的会更快。其中需要关注的参数及其细节:

  1. --clean 参数可以清理临时文件
  2. --windowed 参数避免显示控制台窗口
  3. --onefile 参数将所有文件打包成单个exe
  4. 图标文件需要是.ico格式
  5. 生成的文件会在dist目录下

其实到这里就已经打包完成。

在编译的时候第二个Unix可执行文件已经上传到github,

4. 打包优化

优化打包大小的策略有:

  1. 使用UPX压缩可执行文件
  2. 排除不必要的模块
  3. 清理临时文件和缓存
  4. 优化依赖引入
代码语言:bash
复制
# 使用UPX压缩
pyinstaller --clean --windowed --onefile --upx-dir=/path/to/upx --name "表单填写工具" form_filler.py

# 排除不需要的模块
pyinstaller --clean --windowed --onefile --exclude-module tkinter --name "表单填写工具" form_filler.py

问题总结

其实这是第一个很小的工具开发,感觉其实挺简单的,但是在实际开发中也是遇到了很多的问题,不过大部分都已经解决。最后的问题就是pyinstaller打包带来的问题。目前主要是运行打包后的程序时,因为涉及一些解压等操作,程序响应比较慢,这个应该算是通病。

所以我还是建议使用shell的方式调用py文件比较速度,在我的shell目录下创建一个TencentFill.sh文件并编辑。

代码语言:bash
复制
#!/bin/bash
# 有的macos是.zprofile
source ~/.bash_profile
# 替换成你的项目路径
cd ~/app/cursor/TencentFill
python3.10 form_filler.py

然后给脚本添加执行权限:

代码语言:bash
复制
chmod +x TencentFill.sh

因为我的shell目录添加在了PATH中,所以我在终端通过直接执行TencentFill.sh就能实现表单自动填写。

结语

本篇文章主要从一个表单的自动填写,讲述了如何使用selenium自动化工具 + 图形化实现一个简单的桌面应用,以此来解放双手,替我们完成重复的工作。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 项目介绍
  • 需求分析
    • 技术架构
  • 程序开发
    • 后台逻辑
      • 1. 表单填写
      • 2. 点击事件
    • GUI页面设计
      • 1. 主窗口布局
      • 2. 按钮设计
      • 3. 电话号码验证
    • 个人信息管理
      • 1. 默认配置定义
      • 2. 配置管理
      • 3. 首次使用检测
      • 4. 修改检测
      • 5. 功能验证
    • 程序打包
      • 1. 依赖安装
      • 2. 打包命令
      • 4. 打包优化
  • 问题总结
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档