Windows下用Git Bash搭建Selenium自动化项目:环境、虚拟环境与GitHub推送全记录

📅 发布时间:2026/10/10 13:54:09
Windows下用Git Bash搭建Selenium自动化项目:环境、虚拟环境与GitHub推送全记录
上周帮同事迁移一个 web 自动化项目从一台 Windows 旧电脑搬到新电脑过程绕了不少远路。Git Bash 环境准备、Python 虚拟环境重建、最后把项目推到 GitHub每个环节都有 Windows 下面特有的坑我挨个踩完又爬出来后觉得这套流程值得完整复盘一遍给后来的人当个参照。如果你手头刚好有一个基于 Python 和 Selenium 的 web 自动化小项目日常习惯在 Git Bash 里跑脚本偶尔要把代码推到 GitHub 托管或者虚拟环境已经乱到想直接删了重来这篇应该能帮你省掉不少试探时间。我会把环境准备、项目操作、GitHub 推送、虚拟环境重建这四件事讲透最后再把我实际踩过的坑和现在的固定习惯一并交底。1. 为什么我坚持用 Git Bash 而不是 CMD 来跑 web 自动化项目1.1 Git Bash 解决了 Windows 下哪个真正的痛点Git Bash 本质上是 Git for Windows 自带的模拟环境它给你提供了 bash shell 和一套精简的 GNU 工具集包括 grep、awk、sed、curl、ssh、scp 这些在 Linux/macOS 上习空见惯的命令。做 web 自动化的人应该深有体会网上绝大多数 Selenium、pytest、CI 脚本示例都是按 Linux 习惯写的命令里的斜杠、环境变量、管道符风格全是 Unix 逻辑。你在 Windows 自带的 CMD 或 PowerShell 里跑经常出现路径分隔符不认识、命令不存在的尴尬情况而在 Git Bash 里基本能无缝照跑。还有一个很实际的原因Git Bash 天然把 bash 和 Git 绑在一起。同一个窗口里既能输入 Linux 风格的命令又能直接操作 git不需要在 CMD 和 PowerShell 之间来回切换。我个人的体感是只要你不涉及需要 Windows API 的复杂脚本Git Bash 就是 Windows 上最接近开发环境一致性的解决方案。很多 web 自动化教程默认你用的是 Mac 或 Linux有了 Git Bash你就可以把教程里的命令原样执行少一层翻译成本。提示Git Bash 不等于 Git 的全部它只是 Git for Windows 内置的一个终端环境。你的项目本身不需要依赖 Git Bash 才能运行但开发过程用它会顺手很多。1.2 安装选项里的三个坑PATH、换行符、终端模拟器Git for Windows 的安装包基本可以一路下一步但有几个关键选项建议动手改一下否则后面很容易出问题。第一个是 PATH 环境变量。安装向导会问你要不要调整 PATH默认选 Use Git from the command line 就行这样你在 CMD 和 PowerShell 里也能直接敲 git。如果你只希望在 Git Bash 里面用 git选 Use Git from Git Bash only 也可以。我的习惯是选第一个因为偶尔需要在 PowerShell 里跑一条 git 命令不想为此再开一个窗口。第二个是换行符转换。这个我强烈建议选 Checkout as-is, commit as-is也就是不做自动转换。Windows 下文件默认是 CRLF回车换行Linux/macOS 下是 LF仅换行。如果你选了自动转换Git 会把检出和提交的换行符来回折腾同一个文件在你的工作区和仓库里的字节状态不一致后面排查起来非常折磨人。具体影响我放到第三章细讲。第三个是终端模拟器。默认是 MinTTY我建议保持默认。MinTTY 对 ANSI 颜色的支持更好还能用 CtrlShiftC/CtrlShiftV 来复制粘贴。如果你选了 Windows 自带控制台窗口某些 bash 插件的显示效果会大打折扣。1.3 开工前先做一轮环境体检装好 Git Bash 后别急着开始建项目先把环境状态摸一遍。我每次换机器都会跑这几条命令确认基线git --version bash --version where python python --versionwhere python在 Git Bash 里的输出很重要它告诉你在当前环境里输入 python 时系统找的是哪个路径的 Python。我曾经在同一台机器上装过 Anaconda 和官方 Python两个版本的Python 环境都注册到了 PATH 里结果在 Git Bash 里敲 python 时到底进的是哪个解释器完全取决于 PATH 顺序。这种隐患如果你不检查等到创建虚拟环境时就会踩大雷后面再说。另外顺手配一下 Git 的全局身份信息避免首次 push 时被 Git 拒收git config --global user.name Your Name git config --global user.email youexample.com这一步属于典型的多做不亏、少做必坑操作。邮箱最好和 GitHub 账号的邮箱一致否则提交记录不会关联到你的 GitHub 头像和贡献图上。2. 从零搭建 web 自动化项目虚拟环境是关键的第一道屏障2.1 目录结构、git init 和 .gitignore 的先后顺序很多新手一上来就把项目文件散落在桌面或者下载目录里等代码堆到几十个文件才想起建仓库那时很多无用的缓存文件已经混进来了。我的做法是三步走。第一步先建一个干净的目录结构。以 web 自动化项目为例我习惯这样组织mkdir -p web-automation/tests cd web-automation-p参数会一次性创建多级目录。tests 目录专门放 pytest 用例根目录放项目入口脚本和配置文件。这个结构虽然简单但可以让 git 跟踪范围从一开始就是清晰的。第二步立刻执行git init。在写任何代码之前就把仓库建好这样每一步修改都有迹可循。如果你写了三天代码才想起来 git init初始提交会一次性塞进几十个文件的完整快照出了问题时根本没法定位是哪一步改坏的。第三步写.gitignore。web 自动化项目里最需要忽略的几类东西是虚拟环境目录、Python 缓存、pytest 缓存、IDE 配置和日志文件。我常用的基础版本是.venv/ __pycache__/ .pytest_cache/ *.pyc .DS_Store logs/注意.venv/这行没有它你就会把整个虚拟环境提交到 GitHub动辄几百兆而且别人 clone 下来也用不了。这个错误我在刚学 Git 时犯过一次后来每次建仓都特别检查.gitignore里有没有这一行。2.2 在 Git Bash 里创建并激活虚拟环境路径不一样虚拟环境的核心价值一句话就能说清楚让每个项目的依赖互相隔离。web 自动化项目经常会碰 Selenium 4 和 Selenium 3 的 API 差异如果两个项目共用全局 Python 环境升级其中一个的依赖另一个就可能在运行时突然报错。虚拟环境就是把这个风险锁死在一个目录里。创建虚拟环境的命令很简单难的是激活。在 Git Bash 里激活路径和 CMD 完全不同这一点我必须强调python -m venv .venv source .venv/Scripts/activate注意是Source Scripts/activate不是 CMD 里的.venv\Scripts\activate.bat也不是 PowerShell 里的.\venv\Scripts\Activate.ps1。很多人照着 CMD 的习惯在 Git Bash 里敲.venv\Scripts\activate结果就是一堆报错。因为 Git Bash 走的是 bash 语法激活脚本的入口是Scripts目录下那个不带扩展名的activate文件。激活成功以后命令行提示符前面会出现一个(.venv)标识。有了这个标识你就知道当前所有 pip 安装操作都落在虚拟环境里不会污染全局环境。我见过有人激活失败但没注意提示符接着用 pip 安装了整套依赖到全局环境里最后项目跑起来倒也正常但全局环境被搞得一团糟后来清理时非常痛苦。2.3 用 requirements.txt 锁依赖别让环境变成黑盒依赖管理我习惯用一个朴素但可靠的办法requirements.txt。在虚拟环境里装完你需要的包之后立刻执行pip freeze requirements.txt这样会把当前环境里所有包名和精确版本号导出来。web 自动化项目最典型的依赖组合是 selenium、webdriver-manager、pytest、pytest-html如果你的项目涉及接口请求还会加上 requests。有人会问为什么不直接pip install selenium pytest然后靠记忆维护因为环境的可复现性全靠这份清单。两周后你再回来看项目或者同事 clone 了你的仓库只要pip install -r requirements.txt就能把环境恢复到和你完全一致的状态。版本不一致导致的在我机器上明明是好的问题在自动化项目里尤其常见特别是 webdriver 和浏览器版本不匹配时简直是重灾区。有一个经验供参考不要直接复制 requirements.txt 里的全部内容去手动安装它可能有几十行其中不少是间接依赖手动挑选容易漏。直接pip install -r requirements.txt是最可靠的。2.4 最小可运行的 Selenium 脚本长这样搭建完环境你需要一个能立刻验证环境是否健康的最小脚本。我每次建完环境都会用一个极简的 Selenium 冒烟测试来验证from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager driver webdriver.Chrome(serviceService(ChromeDriverManager().install())) driver.get(https://example.com) print(页面标题:, driver.title) driver.quit()这里用webdriver-manager自动下载和浏览器版本匹配的 ChromeDriver省去手动下载 driver 再配置路径的麻烦。很多 web 自动化项目的第一步卡就卡在 driver 版本对不上webdriver-manager 直接把这个问题抹平了。这个脚本能跑通说明三件事虚拟环境激活正常、基础依赖安装完整、浏览器驱动链路通畅。接下来再往里面加页面元素定位、显式等待、断言逻辑就都是水到渠成的事了。不过自动化脚本里等待策略要特别注意别用隐式等待对付所有场景那是另一个大坑这里不多展开。3. GitHub 推送分支、令牌凭证和换行符三个坎3.1 为什么 GitHub 密码推不上去PAT 和 SSH 二选一2021 年开始GitHub 就取消了密码方式推送。你输入旧密码肯定会看到类似remote: Support for password authentication was removed的报错这是很多新人第一次 push 失败的经典原因。现在主流做法是二选一个人访问令牌PAT或 SSH 密钥。我个人的建议是如果主要在 Windows Git Bash 里用 HTTPS 方式配一个 PAT 加 Git Credential Manager 最省事如果你已经生成过 SSH 密钥走 SSH 协议也很稳定。PAT 的生成路径在 GitHub 网站Settings - Developer settings - Personal access tokens - Tokens (classic) - Generate new token。生成时勾选repo权限范围即可有效期可以设短一点比如 90 天。这个 token 只在生成那一刻完整显示一次之后想再看也看不到了所以生成后要立刻保存到一个安全的地方。3.2 第一次从本地推到远程的完整命令假设你已经在 GitHub 上创建了一个空仓库本地项目也已经 git init 完成第一次推送的完整流程是这样git add . git commit -m init: web automation project git branch -M main git remote add origin https://github.com/yourname/web-automation.git git push -u origin maingit branch -M main的原因很简单新版 GitHub 把默认分支调整成了 main而你本地仓库新建时可能还用旧习惯创建了 master-M 直接改名为 main避免推送时本地和远程分支名不一致。首次执行git push时如果用的是 HTTPS 方式Git 会弹出窗口要求输入用户名和密码。用户名填 GitHub 账号密码的位置填的是 PAT不是你的登录密码。我见过太多人在这里反复输入自己的 GitHub 登录密码一直报错其实只要换成 PAT 就立即通过了。如果想让 Git 记住这个凭证先在本地配置一次 credential helpergit config --global credential.helper manager配置之后第一次弹出窗口验证成功后续推送就不需要再输 token 了。3.3 CRLF 和 LF跨平台团队的头号隐形刺客换行符问题我前面提了一嘴这里展开讲。Windows 上文件换行默认是\r\nCRLFLinux 和 macOS 上是\nLF。Git 里有一个core.autocrlf配置它会在提交和检出时做换行符转换本意是为了让跨平台协作更顺滑但实际运作时经常帮倒忙。最简单也最省心的配置是关闭自动转换让 Git 如实保存文件字节git config --global core.autocrlf false如果你和其他同事的协作环境主要是 Linux/macOS可以用input模式它会在提交时把 CRLF 转成 LF检出时不转git config --global core.autocrlf input这两种配置我都用过目前个人更倾向于false因为input模式下你在 Windows 里编辑文件再提交Git 会警告LF will be replaced by CRLF虽然不影响结果但每次都弹警告很烦。如果仓库里已经混入了大量 CRLF 文件最粗暴但有效的修正方式是一次性重规范化git add --renormalize . git commit -m Fix line endings执行完这次提交仓库里的文件统一成 LF后续所有人在任何平台上检出就不会再出现莫名其妙的^M字符了。这个坑在 web 自动化项目里尤其痛苦因为如果 CI 环境是 Linux而你本地全是 CRLF流水线里跑出来的脚本经常报语法错误或者断言失败但你在本地怎么跑都是对的。4. 虚拟环境翻车后的重建姿势别修直接重来4.1 什么症状说明环境已经救不回来了虚拟环境这个目录看似只是几个文件夹内部却藏着大量绝对路径。你在旧电脑的C:\Users\oldname\web-automation\.venv创建了环境把它整个拷到新电脑后新电脑的用户名不一样、项目路径不一样里面的 python.exe、pip.exe 就全找不到原路径了激活脚本也会报No such file or directory或者bad interpreter。常见的翻车症状包括source .venv/Scripts/activate报错、python --version显示的还是全局 Python、pip 装包时提示找不到系统路径、或者 import selenium 时 ModuleNotFoundError 但明明已经装过了。遇到这些情况我的建议是放弃修复直接重建。因为虚拟环境不像普通项目文件它和机器的路径、Python 版本强绑定手动改内部配置文件很容易把环境搞得更糟成本远高于重建。4.2 重建前先做一次依赖逃生备份重建环境的唯一安全前提是你手里有完整的依赖清单。如果项目一开始就用了pip freeze requirements.txt那清单已经有了。如果没做也别慌可以在旧环境里补救一次pip freeze requirements.txt pip list --formatfreeze两条命令的区别在于某些情况下pip freeze会输出package file:///...这样的本地路径形式而 pip list 的 freeze 格式更贴近常规依赖描述。如果你的 requirements.txt 里出现了大量 file://行建议手动清理一下只保留包名和版本号否则在新机器上执行pip install -r requirements.txt时会尝试去找旧电脑上的文件路径直接报错。对 conda 用户来说备份方式稍有不同。conda 的环境导出命令是conda env export environment.yml导出的 yml 里会带一个prefix行记录了当前机器的环境路径。换机器恢复时记得删掉这一行否则 conda 会尝试在旧路径上重建环境。4.3 venv 重建五连删、建、激活、装、验证依赖清单在手重建就是一套标准动作。我在新环境上执行的操作顺序是deactivate rm -rf .venv python -m venv .venv source .venv/Scripts/activate python -m pip install --upgrade pip pip install -r requirements.txt注意rm -rf .venv在 Git Bash 里没问题但千万别在 Windows 的资源管理器里直接删有些只读文件会卡住删除流程。删掉旧环境是为了确保没有残留文件干扰新环境创建。建好新环境后我习惯先升级 pip 再装依赖。因为 Python 自带的 pip 版本通常偏旧解析依赖和下载速度都会慢不少尤其当你安装的包有大量依赖时旧版 pip 可能直接安装失败。装完包之后验证环节不能省python -c import selenium; print(selenium.__version__) pytest --version两步验证分别确认第三方包和测试框架是否就位。如果这里没报错说明重建已经完成接下来项目脚本直接就能跑。4.4 conda 用户怎么办env export / create / remove 对照表如果你用的是 Anaconda 或 Miniconda 而不是原生 venv流程会略有不同。venv 的机制是纯目录隔离不能跨机器迁移conda 则多了一套环境管理机制。下面这个表是我经常拿出来对照的操作venv 命令conda 命令创建环境python -m venv .venvconda create -n myenv python3.11激活环境source .venv/Scripts/activateconda activate myenv导出依赖pip freeze requirements.txtconda env export environment.yml从文件恢复pip install -r requirements.txtconda env create -f environment.yml删除环境删除目录即可conda remove -n myenv --allconda 的优势在于它连 Python 解释器版本本身也管起来所以conda create -n myenv python3.11可以指定新版 Python而 venv 只能基于你当前系统已安装的解释器来创建。如果你的某个项目需要 Python 3.11另一个需要 3.9conda 会更顺手。但如果你不想装额外的包管理器venv 本身也完全够用关键是保持项目环境与依赖清单的一致性。5. 这套流程里我实际踩过的坑和最终留下的习惯5.1 git bash 里 screen 不存在为什么我会踩这个坑有一次我在 Git Bash 里敲screen -S proxy想挂起一个自动化任务结果终端直接返回bash: screen: command not found。这个坑的本质原因是 screen 是一个 Linux 终端复用工具Git for Windows 的 bash 环境根本没有内置它也不建议在 Windows 上硬装一个 Cygwin 版本来模拟。我的替代方案是把耗时长的 web 自动化任务改成后台运行或者干脆打开一个新的 Git Bash 窗口来跑独立任务。真需要在后台跑批次任务时用 nohup 的方式更贴近 bash 生态nohup python run_tasks.py 如果你习惯一个窗口里同时调度多个耗时的浏览器自动化脚本更优雅的方式是做任务队列而不是依赖终端复用。这个意识我现在已经养成了Windows 生态下的工具边界要先确认再使用不要在 Git Bash 里硬套 Linux 的全部心智模型。5.2 Git Bash 的复制粘贴CtrlC 不是复制Windows 用户刚上手 Git Bash 时最容易误伤的操作就是复制粘贴。在默认的 MinTTY 终端里CtrlC 是发送中断信号不是复制。如果你在浏览器自动化脚本跑得正欢时想复制一段文字按下 CtrlC 的结果通常就是脚本被中断驱动窗口瞬间关闭。这个错误我犯过不止一次每次都是血泪教训。正确姿势是 CtrlShiftC 复制、CtrlShiftV 粘贴。或者你也可以在终端窗口上用鼠标选中文字然后按中键完成复制粘贴这个操作路径在 MinTTY 里同样有效。如果你想彻底改变这个习惯也可以在 Git Bash 窗口标题栏右键进入 Options 里把复制快捷键改成和 Windows 一致但我个人觉得没必要直接适应 MinTTY 的快捷键更高效。5.3 Marktext 里 bash 代码块自动换行的小设置用 Marktext 写技术笔记的人应该遇到过这个问题一篇文档里贴一段超长的 bash 命令Marktext 默认不换行代码块横向拉得很长阅读时被迫来回滚动体验极差。Marktext 在较新版本里提供了代码块软换行选项一般位于 Preferences 的 Markdown 相关设置项下找到类似 Code Block Soft Wrap 的开关打开后长命令就会自动折行显示。如果你的版本里找不到这个选项我建议直接升级到最新版。实在找不到软换行开关时还有一个土办法就是养成写命令时主动折行的习惯用反斜杠把长命令拆成多行。这样不管在任何编辑器里阅读代码都是清晰整齐的python run_task.py \ --env prod \ --browser chrome \ --headless5.4 来路不明的 curl 管道 base64 命令一律不执行最后这条属于安全习惯但我觉得必须提。网上不少一键安装脚本会让你复制一串以bash -c $(curl ...)开头、中间还套着 base64 解码的命令执行完也不知道它到底往系统里放了什么东西。我对所有形如bash -c $(curl ... | base64 --decode)的命令保持高度警惕。看到这种命令先问三件事这个脚本是谁维护的我能不能完整读到脚本内容它为什么要用 base64 混淆正常开源工具都会提供可读的安装文档不需要让你执行一串谁都看不懂的加密字符串。尤其在你自己的开发机器上这种命令轻则装一堆垃圾软件重则可能泄漏你 Git Bash 里的凭证和 SSH 密钥。我的原则很简单看不懂的脚本不执行来源不明的安装命令不复制需要安装工具就去找官方文档按步骤来。这个原则帮我挡住了很多潜在风险也希望你能用上。