SELECTED PROJECTS

Python 小工具集:浏览器、代理与邮件脚本

整理日常自动化脚本的模块边界、依赖管理和异常处理经验。

阅读设置

项目文稿说明:本文按现有笔记整理,代码是节选或设计示意;仓库实现、线上地址和测试结果尚未逐项核验。后续计划不代表已经完成。

从零打造一个 Python 小工具集:browser_manager、代理网关与自动化脚本

菜牙爱吃菜 · 技术随笔


大家好,我是菜牙。

今天想聊聊我一直在维护的一个小项目——tools。说它小,是因为它没有宏大的架构,也没有几十万行代码,就是一堆"小而实用"的 Python 脚本集合。但正是这个"小工具集",让我踩了不少坑、学到了不少东西,今天拿出来和大家分享一下。

这个项目是干什么的?

一句话总结:把日常重复性的工作自动化掉。

比如:

  • 同时开好几个浏览器,每个浏览器走不同的代理(多账号操作)
  • 用 GoLogin 管理大量浏览器指纹,自动登录、切换环境
  • 通过代理网关统一管理多个代理 IP 的轮换和分配
  • 用 IMAP 协议自动处理邮件验证码
  • 管理和重置 Cursor AI 的账号配置

这些东西单独看都很琐碎,但组合在一起,就是一套"多账号运营 + 自动化"的基础设施。

模块一览

项目目前包含以下核心模块:

模块 功能简述
browser_manager 浏览器隔离管理,每个实例绑定独立代理
cursor Cursor AI 账号管理(注册、重置、配置)
gateway_standalone 代理网关,统一管理多个代理出口
gologin_auto GoLogin 浏览器指纹自动化
kookeey Kookeey 代理网关集成
reset_cursor Cursor 账号重置工具
test_imap IMAP 邮件读取测试脚本;发送通常使用 SMTP

每个模块都是独立的,可以单独使用,也可以组合起来用。这种"松耦合"的设计让我可以按需扩展,不用动整体架构。

技术栈

项目用到的技术:

  • PyQt6:给部分工具做了简单的 GUI 界面,不用每次都敲命令行
  • DrissionPage:一个国产的浏览器自动化库,API 设计得很顺手,比 Selenium 简洁不少
  • Selenium:老牌浏览器自动化方案,复杂场景还是得靠它
  • SQLite:本地轻量存储,保存账号信息、代理配置等
  • requests:HTTP 请求,代理网关和 API 调用的基础
## 一个典型的代理网关请求示例
import requests

proxies = {
    "http": "http://127.0.0.1:7890",
    "https": "http://127.0.0.1:7890",
}

resp = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
print(resp.json())

踩过的坑和学到的东西

1. 浏览器隔离是个大坑

浏览器实例若复用同一用户数据目录,可能共享 Cookie 和 localStorage;普通 WebDriver 新会话不必然串数据。后来改用独立的用户数据目录(--user-data-dir)+ 独立代理的方式,才算真正实现了浏览器隔离。

## browser_manager 中的核心思路
def create_browser(proxy_port: int, user_data_dir: str):
    options = Options()
    options.add_argument(f"--proxy-server=http://127.0.0.1:{proxy_port}")
    options.add_argument(f"--user-data-dir={user_data_dir}")
    # 反检测:去掉 webdriver 标记
    options.add_argument("--disable-blink-features=AutomationControlled")
    return webdriver.Chrome(options=options)

教训:浏览器隔离不是加个代理就完事,用户数据目录才是关键。

2. 代理网关设计要考虑失败重试

代理 IP 是会过期的,尤其是免费代理。一开始我的网关逻辑很简单:请求 → 返回结果。后来频繁遇到超时、403 等问题,加了自动重试 + 代理池轮换之后才稳定下来。

def request_with_retry(url, max_retries=3):
    for i in range(max_retries):
        proxy = get_next_proxy()  # 从代理池取下一个
        try:
            return requests.get(url, proxies=proxy, timeout=10)
        except Exception as e:
            mark_proxy_failed(proxy)  # 标记失效
            if i == max_retries - 1:
                raise

教训:写网络相关代码,永远要考虑失败的情况,并做好重试和降级。

3. 环境变量管理别偷懒

项目里有很多 API Key、密码、代理地址这类敏感信息。一开始我图方便直接硬编码在代码里,后来有一次差点把 .env 文件推到 Git 仓库——还好 .gitignore 挡住了。

现在 .env.example 模板 + python-dotenv 已经是标配:

## .env.example
CURSOR_API_KEY=your_api_key_here
GOLOGIN_TOKEN=your_token_here
KOOKEEY_API_KEY=your_api_key_here
PROXY_POOL_URL=http://your-proxy-pool:8080
from dotenv import load_dotenv
load_dotenv()

import os
api_key = os.getenv("CURSOR_API_KEY")
if not api_key:
    raise ValueError("缺少 CURSOR_API_KEY,请检查 .env 文件")

教训:敏感信息一定要放环境变量,.env 文件一定要加到 .gitignore。

4. GUI 不用太复杂

用 PyQt6 做界面的时候,我一开始想做个"现代化"的深色主题、多标签页、可拖拽布局……后来发现完全没必要。使用者就是我自己,一个简单的表格 + 几个按钮就够了。

教训:工具类软件的界面,能跑就行,别过度设计。

一些反思

做完这个项目之后,我有几个比较深的感受:

  1. 小工具也有架构:虽然叫"小工具集",但模块之间的依赖关系、数据流向还是要理清楚。没有架构的小工具,之后维护起来就是灾难。

  2. 自动化脚本的核心不是代码,是异常处理:正常情况下谁都写得出来,真正体现水平的是各种异常情况的处理——网络超时、代理失效、账号被封、页面改版。

  3. 写文档很重要:这个项目我断断续续维护了好几个月,中间有好几次隔了快一个月再来看代码,发现自己都忘了某些模块是干什么的。所以现在强制自己写 README 和注释。

  4. 保持简单:这个项目没有用 Docker、没有用微服务、没有用消息队列——因为不需要。过度工程化比不工程化更可怕。

最后

如果你也在维护类似的小工具集,欢迎交流。这种项目没什么"高大上"的东西,但确实能实实在在地提升效率。

代码不复杂,但每一行都是真实踩坑之后的结晶。


菜牙爱吃菜,一个爱折腾的开发者。欢迎关注,持续分享实用小技巧。

PythonSeleniumSQLiteIMAP