Git 使用手册 · 终极篇:工程化、安全与团队规范

这是 Git 手册系列的最后一篇。前三篇解决了"会用 → 用得对 → 懂原理",本篇解决最后一件事:让 Git 在团队和工程体系里成为可靠的基础设施,并在灾难发生时救得回来。 目录 Monorepo vs Polyrepo:仓库拓扑决策 大型仓库的性能优化 提交规范:Conventional Commits 签名提交与提交者验证 密钥防护:从预防到泄漏处置 CI/CD 中的 Git 技巧 灾难恢复 SOP 一套可直接落地的团队 Git 规范 终极速查表 Monorepo vs Polyrepo:仓库拓扑决策 Monorepo(一个仓库存所有项目) Polyrepo(每项目一个仓库) 跨项目改动 一次提交原子完成 要发版、升依赖、多 PR 联动 代码共享 直接 import 发包 / submodule CI 需要增量构建,配置复杂 简单直接 权限边界 靠 CODEOWNERS,粒度粗 天然隔离 克隆体积 大(可用 sparse checkout 缓解) 小 代表 Google、Meta、Vue、React 生态 多数中小团队 决策建议: 项目间强耦合、频繁联动发布(如前端组件库 + 应用)→ monorepo 团队/项目独立、发布节奏不同、需要强权限边界 → polyrepo 不确定就先 polyrepo;拆容易,合回去很难 monorepo 配套工具:Nx、Turborepo、Bazel(构建缓存与增量)、changesets(多包版本管理)。 ...

2026-08-22 · 4 分钟 · 737 字 ·   · heyaohua

Git 使用手册 · 高级篇:原理、调试与仓库工程

这是 Git 手册系列的第三篇。前两篇讲"怎么用",本篇讲"为什么":理解了 Git 的内部模型,所有命令都会变成推理题而非背诵题;再配上一批工程化工具,解决"什么时候出的 bug"、“仓库太大”、“多仓库依赖"这类真实难题。 目录 Git 对象模型:blob、tree、commit、tag 引用:分支、HEAD、tag 都只是指针 彻底理解 merge / rebase / cherry-pick bisect:二分查找"哪次提交引入了 bug” worktree:一个仓库多个工作区 submodule 与 subtree:仓库套仓库 hooks:在关键时刻自动执行脚本 Git LFS 与大文件 仓库瘦身:清理历史中的大文件 高级调试与诊断 Git 对象模型:blob、tree、commit、tag Git 本质是一个内容寻址的文件系统 + 一个版本控制外壳。.git/objects/ 下只有四种对象: 对象 内容 类比 blob 文件的内容(不含文件名) 文件快照 tree 一个目录:文件名 → blob/tree 的指针列表 文件夹快照 commit 指向一个 tree + 父 commit 指针 + 作者/时间/信息 一次版本 tag(附注) 指向一个 commit + 标签信息 里程碑 所有对象用内容算 SHA-1(新版支持 SHA-256)哈希作为 id:内容相同 → id 相同,这就是 Git 去重和完整性校验的原理。 ...

2026-08-22 · 4 分钟 · 832 字 ·   · heyaohua

Git 使用手册 · 中级篇:分支协作、冲突与历史修改

这是 Git 手册系列的第二篇。初级篇解决了"能用",本篇解决"用得对":多人协作不打架、冲突不慌、历史能改得干净。 目录 分支模型:选一个然后坚持 merge 与 rebase:到底用哪个 冲突的正确解法 reset 的三种模式(soft / mixed / hard) stash:临时收摊子 cherry-pick:挑一个提交带走 修改历史:amend 与交互式 rebase reflog:你的后悔药 tag 与发布 中级常见错误 分支模型:选一个然后坚持 个人 / 小团队:Trunk-Based(主干开发) main 是唯一长期分支,随时可发布 功能分支从 main 切出,活 1~3 天,合并后立即删除 配合 PR/MR 做代码评审 1 2 3 4 5 git switch -c feature/xxx main # 开发、提交 git push -u origin feature/xxx # 提 PR,评审通过后合并 git switch main && git pull git branch -d feature/xxx 需要同时维护多个发布版本:Git Flow main:线上版本;develop:集成分支 feature/*、release/*、hotfix/* 各司其职 重,只有确实需要多版本并行(如 SaaS + 私有化部署)才用 结论:90% 的团队用 Trunk-Based 就够了。分支模型越简单,协作成本越低。 ...

2026-08-22 · 4 分钟 · 681 字 ·   · heyaohua

Git 使用手册 · 初级篇:从第一次提交开始

这是 Git 手册系列的第一篇。目标只有一个:让你今天就能用 Git 管好自己的代码,并且知道每条命令在干什么。不理解原理没关系,先把工作流跑通。 目录 Git 是什么,解决什么问题 安装与初始配置 四个区域:工作区、暂存区、本地仓库、远程仓库 第一次提交 日常三板斧:status / add / commit 查看历史 撤销与回退(安全版) 连接远程仓库(GitHub / GitLab) 分支是什么(先会用最基础的) 初级常见错误 Git 是什么,解决什么问题 没有 Git 的时候,你是这样管理代码的: 1 2 3 4 project/ project-final/ project-final-v2/ project-final-v2-真的最终版/ Git 做的事:把项目的每一次修改记录成"快照"(commit),你可以随时查看任何历史版本、回到任何历史版本、同时维护多条并行的修改线(分支),并和别人协作而互不覆盖。 安装与初始配置 1 2 3 4 5 6 7 # macOS brew install git # Ubuntu / Debian sudo apt install git # Windows:安装 Git for Windows(自带 Git Bash) 第一次使用必须先配置身份,否则提交会带上机器默认的匿名信息: ...

2026-08-22 · 3 分钟 · 587 字 ·   · heyaohua

PM2 使用手册:从安装到生产级进程管理

PM2 是 Node.js 生态中最常用的生产级进程管理器,但它的能力不止于"让 Node 脚本在后台跑起来"。本文从安装讲起,覆盖日常管理、集群、日志、监控、自启与生产部署的完整流程。 目录 安装与基础概念 启动与进程管理 ecosystem 配置文件 集群模式(Cluster Mode) 日志管理 监控与指标 开机自启 零停机重载与发布 内存与异常处理策略 常见坑与排查 速查表 安装与基础概念 1 2 3 4 5 # 全局安装 npm install -g pm2 # 或 pnpm pnpm add -g pm2 PM2 的核心概念只有三个: process:被 PM2 托管的一个应用实例 daemon:PM2 自身驻留后台的管理进程(~/.pm2/ 下保存状态) ecosystem file:声明式配置文件(ecosystem.config.js),推荐的生产方式 验证安装: 1 2 pm2 -v pm2 ping # 检查 daemon 是否存活 启动与进程管理 启动一个应用 1 2 3 4 5 6 7 8 9 10 11 12 # 最简单的启动 pm2 start app.js # 指定进程名(强烈建议,否则默认用文件名) pm2 start app.js --name api-server # 传递 Node 参数与应用参数 pm2 start app.js --name api --node-args="--max-old-space-size=2048" -- --port 3000 # 不限于 Node:任何可执行文件都可以托管 pm2 start python --name spider -- main.py pm2 start ./worker.sh --name job 常用管理命令 1 2 3 4 5 6 7 pm2 list # 进程列表(别名 pm2 ls / pm2 status) pm2 describe api-server # 单个进程详情:路径、日志位置、重启次数、内存等 pm2 restart api-server # 重启 pm2 reload api-server # 优雅重载(集群模式下零停机) pm2 stop api-server # 停止(保留在列表中) pm2 delete api-server # 从 PM2 列表移除 pm2 save # 保存当前进程列表快照(供 resurrect / 自启恢复) 所有命令都可以用进程名、进程 id,或 all(全部进程)作为目标。 ...

2026-08-22 · 5 分钟 · 945 字 ·   · heyaohua

淘宝自动化框架选择方案

淘宝自动化框架选择方案 🎯 推荐方案:DrissionPage + 现有架构 为什么选择 DrissionPage? 专为中国网站设计 针对淘宝、京东等电商网站优化 内置常见反爬虫机制绕过 国产框架,中文文档完善 与现有架构完美融合 可以直接使用现有的 requests session 支持与 mitmproxy 代理集成 兼容现有的数据处理管道 性能与易用性并存 基于 Chromium 内核,性能优秀 API 设计简洁直观 支持页面模式和 requests 模式切换 📊 框架对比分析 特性 DrissionPage Playwright Selenium Requests-HTML 性能 很快 最快 中等 快 反爬虫能力 优秀 优秀 一般 较弱 淘宝适配 优秀 好 一般 较弱 学习成本 低 中 中 低 中文文档 优秀 一般 好 一般 社区支持 活跃 活跃 最大 较小 🛠️ 技术实施路线 阶段一:环境准备 1 2 3 4 5 6 # 安装 DrissionPage pip install DrissionPage # 安装备选方案(可选) pip install playwright pip install selenium 阶段二:基础集成 创建 TaobaoAutomator 类 集成现有的代理服务器 实现基础的搜索和数据提取功能 阶段三:高级功能 反爬虫策略优化 数据清洗和存储 错误处理和重试机制 阶段四:性能优化 并发处理 资源管理 监控和日志 💡 备选方案 方案 A:纯 Playwright(如果团队技术能力强) 性能最佳 功能最全面 需要较多学习时间 方案 B:Selenium(如果需要最大兼容性) 社区资源最丰富 兼容性最好 性能相对较慢 方案 C:混合方案 DrissionPage 处理复杂交互 requests 处理简单API调用 mitmproxy 处理数据截取 🎪 具体实现示例 DrissionPage 基础用法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from DrissionPage import ChromiumPage # 创建页面对象 page = ChromiumPage() # 访问淘宝 page.get('https://www.taobao.com') # 搜索商品 search_box = page.ele('#q') search_box.input('手机') search_box.after().click() # 获取商品信息 products = page.eles('.item') for product in products: title = product.ele('.title').text price = product.ele('.price').text print(f"{title}: {price}") 与现有架构集成 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from DrissionPage import ChromiumPage from crawler.gateway.proxy_server import ProxyServer class TaobaoAutomator: def __init__(self): # 启动代理服务器 self.proxy_server = ProxyServer() # 配置 DrissionPage 使用代理 self.page = ChromiumPage() self.page.set.proxy(f'127.0.0.1:{self.proxy_server.port}') def search_products(self, keyword): # 实现搜索逻辑 pass 🔧 技术要点 代理集成:确保自动化框架使用现有的代理服务器 数据同步:截取的API数据与页面数据关联 反爬虫:实现用户行为模拟和请求间隔控制 错误处理:网络异常、页面变化等情况的处理 📈 预期效果 开发效率提升 50%:相比从零开始 数据质量提升:结合API和页面数据 稳定性增强:多重反爬虫策略 维护成本降低:统一的架构设计

2025-09-26 · 2 分钟 · 242 字 ·   · heyaohua

我用Python开发了一个淘宝图片搜索自动化系统

在电商时代,图片搜索已经成为用户发现商品的重要方式。作为开发者,我经常需要为客户批量搜索相似商品并生成报告。手动操作不仅效率低下,还容易出错。于是,我决定开发一个自动化系统来解决这个问题。 项目目标 批量处理图片搜索 自动提取商品数据 生成包含图片的Excel报告 自动发送邮件通知 完整的错误处理和日志记录 技术选型 自动化框架:DrissionPage 经过对比Selenium、Playwright等框架,我选择了DrissionPage: 专为中国网站优化 反爬虫能力强 对淘宝等国内电商支持好 数据拦截:mitmproxy 能够拦截HTTPS流量 支持自定义插件 适合API数据提取 数据处理 Pandas:数据处理 openpyxl:Excel操作 Pillow:图片处理 核心功能实现 1. 图片搜索自动化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def search_by_image(self, image_path: str): """图片搜索功能""" # 1. 打开淘宝首页 self.browser.get('https://www.taobao.com') # 2. 点击搜同款按钮 search_button = self.browser.ele('css:.image-search-icon-wrapper') search_button.click() # 3. 上传图片 file_input = self.browser.ele('css:#image-search-custom-file-input') file_input.input(image_path) # 4. 等待上传完成并搜索 self._wait_for_upload_complete() search_btn = self.browser.ele('css:#image-search-upload-button') search_btn.click() # 5. 提取商品数据 return self._extract_products_from_page() 2. 数据拦截与提取 通过mitmproxy拦截淘宝API响应,提取商品信息: ...

2025-05-26 · 2 分钟 · 383 字 ·   · heyaohua

macOS 终端利器 iTerm2 配置指南

iTerm2 是 macOS 上最强大的终端工具之一,本文将介绍如何安装和配置 iTerm2,让它成为你的得力助手。 安装步骤 1. 安装 iTerm2 有两种安装方式: 直接下载:从 iTerm2 官网 下载,解压后拖到 Applications 目录 使用 Homebrew: 1 brew install --cask iterm2 2. 配置主题 下载 Solarized Dark theme:http://ethanschoonover.com/solarized 打开 iTerm2 偏好设置:Command + , 进入 Profiles -> Colors -> Color Presets -> Import 导入下载的 Solarized Dark.itermcolors 文件 选择 Solarized Dark 主题 3. 安装 Oh My Zsh 一键安装: 1 sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" 设置 Zsh 为默认 Shell: 1 chsh -s /bin/zsh 配置主题: 1 vim ~/.zshrc # 修改 ZSH_THEME="agnoster" 4. 配置字体 下载并安装 Meslo 字体:Meslo LG M Regular for Powerline.ttf iTerm2 配置: 打开偏好设置:Command + , Profiles -> Text -> Font -> Change Font 选择 “Meslo LG M Regular for Powerline” 字体 5. 增强功能配置 5.1 语法高亮 1 2 3 4 5 # 安装 brew install zsh-syntax-highlighting # 配置 echo "source /usr/local/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" >> ~/.zshrc 5.2 自动补全 1 2 3 4 5 6 7 # 安装 git clone https://github.com/zsh-users/zsh-autosuggestions ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions # 配置 vim ~/.zshrc # 在 plugins 中添加 zsh-autosuggestions plugins=(git zsh-autosuggestions zsh-syntax-highlighting) 5.3 快捷键配置 左右键跳转: 打开偏好设置:Command + , Profiles → Keys → Load Preset… → Natural Text Editing ...

2025-05-26 · 2 分钟 · 278 字 ·   · heyaohua

抖音长截图服务使用说明

本文介绍基于 Playwright 封装的抖音长截图服务,涵盖能力范围、接口设计、使用范例以及性能调优建议,便于快速集成到现有业务系统中。 服务概述 核心功能已经封装在 app/services/playwright_service.py 中,经过大量测试验证,推荐使用的默认参数如下: 滚动距离:1000 px 底部裁剪:300 px 平均截图数量:4–5 张 平均文件大小:2–4 MB GitHub 仓库:https://github.com/heyaohua/douyin_screenshot_service 核心能力 移动端模拟:完整模拟 iPhone 设备视口与 UA 智能滚动:自动识别内部滚动容器并控制节奏 懒加载处理:触发页面动态内容渲染 图像拼接:裁剪重叠区域,生成无缝长图 错误处理:封装异常重试、日志与超时机制 主要接口 take_long_screenshot(url, output_dir="screenshots") url:待截图抖音页面 URL output_dir:输出目录(默认 screenshots) 返回值示例: 1 2 3 4 5 6 7 8 9 10 { "success": True, "output_path": "screenshots/douyin_long_screenshot_20250916_135333.png", "screenshot_count": 4, "total_height": 9228, "file_size": 2764800, "original_url": "https://v.douyin.com/...", "current_url": "https://haohuo.jinritemai.com/...", "title": "页面标题" } HTTP API 设计 长截图接口 请求:POST /douyin/long-screenshot 请求体: 1 2 3 { "url": "https://v.douyin.com/Zdo3P7Zv51o/" } 响应: 1 2 3 4 5 6 7 8 9 10 { "message": "长截图完成", "data": { "success": true, "output_path": "screenshots/douyin_long_screenshot_20250916_135333.png", "screenshot_count": 4, "total_height": 9228, "file_size": 2764800 } } 测试接口 请求:POST /douyin/test-long-screenshot 说明:使用预设 URL 触发一次完整流程,便于巡检。 使用示例 服务内调用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from app.services.playwright_service import playwright_service async def example(): await playwright_service.initialize() result = await playwright_service.take_long_screenshot( url="https://v.douyin.com/Zdo3P7Zv51o/", output_dir="screenshots" ) if result["success"]: print(f"截图完成: {result['output_path']}") print(f"截图数量: {result['screenshot_count']}") print(f"总高度: {result['total_height']}px") await playwright_service.close() HTTP API 调用 1 2 3 4 5 curl -X POST "http://localhost:8000/douyin/long-screenshot" \ -H "Content-Type: application/json" \ -d '{"url": "https://v.douyin.com/Zdo3P7Zv51o/"}' curl -X POST "http://localhost:8000/douyin/test-long-screenshot" 本地测试脚本 1 2 cd tests python test_service.py 性能指标 滚动距离 截图数量 平均文件大小 效率评估 1000 px 4–5 张 2.6–3.7 MB ⭐⭐⭐⭐⭐ 推荐参数 900 px 6 张 4.6 MB ⭐⭐⭐⭐ 800 px 6 张 4.3 MB ⭐⭐⭐ 700 px 7 张 5.0 MB ⭐⭐ 600 px 8 张 5.7 MB ⭐ 目录结构 1 2 3 4 5 6 7 8 9 10 11 12 13 app/services/ ├── playwright_service.py # 主服务入口 │ ├── take_long_screenshot # 长截图方法 │ └── _stitch_screenshots # 图片拼接方法 app/api/ ├── douyin.py # HTTP API 定义 │ ├── /long-screenshot # 长截图接口 │ └── /test-long-screenshot # 测试接口 tests/ ├── test_service.py # 集成测试脚本 └── simple_douyin_test.py # 快速验证脚本 运维与实践建议 生命周期管理:调用前需执行 initialize(),结束后务必调用 close() 释放浏览器资源。 目录权限:确保输出目录具备写权限,并定期清理历史截图。 错误兜底:检查返回的 success 字段并结合日志定位问题。 并发控制:视负载设置队列或限流,避免同时创建大量浏览器实例。 监控告警:建议将成功率、耗时、文件大小等指标纳入监控系统。 日志样例 1 2 3 4 2025-09-16 13:53:33,832 - INFO - 拼接图片尺寸: 1170 x 9228 2025-09-16 13:53:35,160 - INFO - ✅ 成功: True 2025-09-16 13:53:35,160 - INFO - 📊 截图数量: 4 2025-09-16 13:53:35,160 - INFO - 💾 文件大小: 2.64MB 成功案例 URL:https://v.douyin.com/Zdo3P7Zv51o/ 截图数量:4 张 总高度:9228 px 文件大小:2.64 MB 处理时长:约 22 秒 成功率:100% 如需深入定制或扩展能力,请参考仓库中的完整代码与测试用例。

2024-01-15 · 2 分钟 · 343 字 ·   · heyaohua

Python开发小技巧分享

日常开发中,掌握一些高频技巧能够明显提升代码质量与效率。本文整理了五个常用的小窍门,并配以示例代码,便于在项目中直接应用。 1. 善用列表推导式 列表推导式可以将循环与条件判断浓缩到一行,既简洁又易读: 1 2 3 4 5 6 7 8 9 10 # 传统写法 squares = [] for x in range(10): squares.append(x**2) # 列表推导式 squares = [x**2 for x in range(10)] # 搭配条件过滤 even_squares = [x**2 for x in range(10) if x % 2 == 0] 2. 使用 dict.get 提升容错性 通过 dict.get 读取字典时,可定义默认值,避免 KeyError 并简化分支逻辑: ...

2024-01-15 · 1 分钟 · 159 字 ·   · heyaohua