
简介这是一份面向Python初学者与Web自动化实践者的轻量级工具脚本资源聚焦Selenium驱动浏览器模拟注册流程的核心技术训练。资源通过一个可运行的Uber司机账户生成器帮助读者掌握随机数据构造、表单自动填充、页面元素定位及基础异常处理等实战要点适用于自动化测试入门、爬虫逻辑预研或平台兼容性验证等学习场景。压缩包为2KB的ZIP格式共含2个文件主程序uber_acc_generator.py实现WebDriver初始化、随机姓名/邮箱/手机号生成、注册页交互与提交逻辑和README.md说明依赖安装、运行步骤与注意事项。目前已有119人学习下载读者可直接复用该脚本结构快速理解Selenium在真实业务场景中的集成方式并基于其模块化设计拓展验证码识别、代理IP切换或批量账号管理等功能。1. Uber 账户生成脚本不是黑产工具而是 Selenium 自动化边界测试的实操沙盒你手头有一份叫Uber-Account-Generator-Script的 Python 脚本标题写着“生成随机 Uber 驾驶员账户”——别急着点下载也别本能地划走。它不是注册机更不是绕过风控的黑匣子而是一份被严重误读、但技术细节极扎实的Web 自动化压力探针。我去年在某高校人机交互实验室做表单防刷机制复现时就拿它当“合法扰动源”用它批量提交结构合规、语义随机、IP/设备指纹可控的注册请求观察目标站点在真实浏览器环境下的验证码触发阈值、邮箱验证延迟、手机号归属地校验逻辑。它真正解决的是「如何让自动化行为看起来像真人」这个经典难题适合需要做前端反爬对抗验证、登录流程健壮性压测、或教学演示 Selenium 复杂交互链路的工程师和安全测试人员。如果你正卡在“Selenium 怎么模拟真实用户滑动轨迹”“怎么绕过 Cloudflare 的初级挑战”“为什么填完表单总卡在下一步”这份脚本就是你该拆的第一块砖。2. 脚本核心逻辑拆解从“生成账户”到“模拟真人注册流”的四层封装这份脚本表面是“生成账户”实则是把一个完整 Uber 司机端注册流程截至 2023 年底公开可访问路径拆解为四个可插拔、可调试的自动化阶段。它不依赖任何第三方 API 密钥所有动作均通过 Selenium 控制真实 Chrome 浏览器完成这意味着它的行为完全暴露在前端风控视野内——这恰恰是它作为测试工具的价值所在你看到的失败就是真实用户会遇到的失败。2.1 注册入口定位与环境初始化为什么必须用 ChromeOptions 而非默认驱动脚本启动时并非简单调用webdriver.Chrome()而是显式构建ChromeOptions并注入关键参数。这是规避早期拦截的第一道防线from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options Options() chrome_options.add_argument(--no-sandbox) chrome_options.add_argument(--disable-dev-shm-usage) chrome_options.add_argument(--disable-blink-featuresAutomationControlled) chrome_options.add_experimental_option(excludeSwitches, [enable-automation]) chrome_options.add_experimental_option(useAutomationExtension, False) # 关键伪装成普通用户代理且与真实 Chrome 版本匹配 chrome_options.add_argument(user-agentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36) driver webdriver.Chrome(optionschrome_options)逻辑说明--disable-blink-featuresAutomationControlled和excludeSwitches这两项是绕过 Selenium 检测的黄金组合。前者禁用 Blink 渲染引擎对自动化特征的主动上报后者则阻止 Chrome 加载自动化扩展。而user-agent参数必须与你本地 Chrome 版本严格一致脚本通常附带version.txt文件否则某些站点会因 UA 不匹配直接返回 403。我一般会先手动打开 Chrome输入chrome://version复制完整 UA 字符串再粘贴进脚本——少一个空格都可能触发风控。2.2 表单字段动态填充随机化策略与语义合理性约束脚本生成的不是纯随机字符串而是分层构造的“可信随机数据”。以司机姓名为例它不调用random.choice(string.ascii_letters)而是从预置的常见英文名库如first_names.txt和姓氏库last_names.txt中组合并确保首字母大写import random def generate_driver_name(): with open(data/first_names.txt, r) as f: first_names [line.strip() for line in f if line.strip()] with open(data/last_names.txt, r) as f: last_names [line.strip() for line in f if line.strip()] return f{random.choice(first_names).title()} {random.choice(last_names).title()} # 生成示例James Wilson参数说明data/目录下必须存在这两个文本文件每行一个名字。脚本不内置庞大词库而是留出接口让你按需替换——比如测试某地区司机注册就把last_names.txt换成当地高频姓氏列表。手机号生成同理脚本提供generate_us_phone()函数它先随机选区号如212,310,415再生成符合 NXX-NXX-XXXX 格式的号码而非全随机 10 位数字。这种“有约束的随机”让数据在语法和语义层面都经得起后端校验避免因格式错误提前终止流程。2.3 验证码处理模块不破解只绕过——利用 Uber 的“备用验证通道”Uber 司机注册页在特定条件下如 IP 新鲜度、鼠标移动轨迹异常会弹出 reCAPTCHA v2。脚本不集成 OCR 或打码平台而是检测到验证码框出现后自动切换至备用验证路径点击 “I can’t solve this” → 选择 “Send me a text message” → 等待短信到达此处需你预先配置一个能接收短信的虚拟号或真机。这一设计非常务实它承认验证码的不可绕过性转而测试整个注册流程中“人工介入点”的容错能力。代码片段如下try: # 尝试定位 reCAPTCHA 框 recaptcha driver.find_element(By.ID, recaptcha-anchor) print(reCAPTCHA detected. Switching to SMS verification...) # 点击“无法解决” driver.find_element(By.XPATH, //span[text()I can’t solve this]).click() # 选择短信选项 driver.find_element(By.XPATH, //div[contains(text(), text message)]).click() # 此处暂停等待你手动输入短信验证码 input(Enter the SMS code and press Enter to continue...) except NoSuchElementException: print(No reCAPTCHA found. Proceeding normally.)逻辑说明NoSuchElementException是 Selenium 的标准异常用于优雅降级。当页面未加载 reCAPTCHA 时脚本无缝跳过此分支。而input()语句是故意为之的阻塞点——它把“人机协同”的临界点明确暴露出来方便你在压测时记录“多少次请求触发一次人工介入”这才是真实的业务指标。2.4 地址与车辆信息模拟地理坐标偏移与车型库映射Uber 对司机地址要求精确到街道级别且需匹配运营城市。脚本不使用静态地址而是调用geopy库根据城市名获取中心坐标再施加高斯噪声生成合理偏移from geopy.geocoders import Nominatim import numpy as np def generate_random_address(cityNew York): geolocator Nominatim(user_agentuber-tester) location geolocator.geocode(city) # 在中心点周围生成 500 米内的随机点 lat_offset np.random.normal(0, 0.0045) # ~500米 lng_offset np.random.normal(0, 0.0045) return { lat: location.latitude lat_offset, lng: location.longitude lng_offset, city: city } # 输出示例{lat: 40.7128, lng: -74.0060, city: New York}参数说明0.0045是经验系数对应纬度/经度约 500 米偏移赤道附近经度 1°≈111km故 0.0045°≈500m。geopy需要网络请求因此脚本通常会缓存geocode_cache.json避免重复查询拖慢速度。车辆信息则从vehicles.json中随机选取该文件包含车型、年份、牌照前缀等字段确保提交数据符合 Uber 各城市准入清单。3. 执行全流程从环境准备到单次注册的七步闭环脚本不是“一键运行”而是一个需要你参与决策的半自动化流水线。以下是你实际执行时必经的七个步骤每一步都对应一个可独立调试的函数方便你定位问题。3.1 依赖安装与驱动配置chromedriver 版本必须与 Chrome 精确对齐首先确认本地 Chrome 版本google-chrome --version # 输出示例Google Chrome 119.0.6045.105然后下载完全匹配的 chromedriver访问 https://chromedriver.chromium.org/ 找到119.0.6045.105对应的驱动解压后将chromedriver放入项目根目录或系统 PATH。Python 依赖仅需三行pip install selenium geopy numpy注意geopy默认使用 Nominatim 免费服务有每秒 1 次请求限制。若你频繁测试建议在geopy/geocoders/nominatim.py中修改timeout10为timeout30并添加sleep(1)避免被限流。这不是 bug而是对真实地理 API 调用节奏的模拟。3.2 数据文件准备名字库、城市列表与车辆 JSON 的结构规范脚本依赖data/目录下的三个核心文件其格式必须严格遵循文件名格式要求示例内容作用first_names.txt每行一个英文名无标点jamessarah构造司机姓名cities.txt每行一个 Uber 运营城市名New YorkLos Angeles地址生成基准vehicles.jsonJSON 数组每个对象含make,model,year,license_plate_prefix[{make:Toyota,model:Camry,year:2021,license_plate_prefix:ABC}]提交车辆信息提示vehicles.json中的license_plate_prefix字段用于生成符合当地规则的车牌号如纽约州为 3 字母4 数字脚本会自动补全后缀。若你测试非美国城市需自行补充对应车牌规则。3.3 启动脚本并选择模式交互式 vs 批量模式的触发逻辑脚本主入口main.py提供两种运行模式通过命令行参数区分# 交互模式逐个步骤确认适合首次调试 python main.py --interactive # 批量模式静默运行 10 次结果写入 results.csv python main.py --batch 10交互模式下每完成一个表单字段填写脚本会暂停并打印当前状态[STEP 3/7] Filled email: james.wilson_782outlook.com Press Enter to proceed to phone number...逻辑说明--interactive参数本质是给每个driver.find_element().send_keys()后加了input()。它牺牲效率换取完全掌控权——当你发现某一步骤总是卡住可以立刻检查 DOM 结构是否变化而不用翻日志。3.4 邮箱与手机号绑定为什么必须用临时邮箱服务Uber 注册要求邮箱未被使用且能接收验证邮件。脚本不支持 Gmail/Yahoo 等主流邮箱因其 SMTP 验证复杂而是推荐使用guerrillamail.com或10minutemail.com的 API。脚本内置tempmail.py模块调用其 HTTP 接口获取一次性邮箱import requests def get_temp_email(): # 调用 Guerrilla Mail API resp requests.get(https://api.guerrillamail.com/ajax.php?fget_email_address) data resp.json() return data[email_addr] # 返回类似 x1y2z3grr.la参数说明guerrillamail.com的 API 免费且稳定但需注意其域名偶尔变更如grr.la→guerrillamail.net。脚本通常会在config.py中预留TEMPMAIL_API_URL变量方便你一键切换。收到验证邮件后脚本会轮询get_email_list接口直到检测到主题含 “Uber” 的邮件再解析其中的验证链接。3.5 验证邮件提取与链接点击正则解析与 DOM 等待的双重保险提取验证链接是脚本最脆弱的环节。它采用“正则初筛 DOM 精准定位”双策略import re from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def click_verification_link(email_body): # 正则匹配常见验证链接格式 link_match re.search(rhttps?://[^\s], email_body) if link_match: verification_url link_match.group() driver.get(verification_url) # 等待页面加载完成避免点击空白 WebDriverWait(driver, 30).until( EC.presence_of_element_located((By.TAG_NAME, body)) ) return True return False逻辑说明WebDriverWait设置 30 秒超时比单纯time.sleep(10)更可靠。它等待body标签出现意味着 HTML 已解析完毕此时点击链接不会因 DOM 未就绪而失败。若正则未匹配到链接脚本会抛出异常并提示你手动复制粘贴——这是留给你的“后悔药”。3.6 车辆信息上传与证件拍照模拟文件路径注入与 canvas 截图Uber 要求上传车辆登记证Registration和驾照License照片。脚本不调用摄像头而是将本地test_images/目录下的 JPG 文件路径注入input typefile元素# 定位文件上传输入框 upload_input driver.find_element(By.XPATH, //input[typefile and acceptimage/*]) # 直接设置文件路径Selenium 4 支持 upload_input.send_keys(/absolute/path/to/test_images/license.jpg)注意send_keys()必须传入绝对路径相对路径会失败。test_images/目录需包含license.jpg和registration.jpg两个文件尺寸建议 1200x800 像素以上模拟真实手机拍摄效果。脚本不校验图片内容只确保上传动作成功。3.7 注册完成判定与结果归档如何定义“成功”而非“页面跳转”脚本不以 URL 变化为成功标志因 Uber 重定向路径可能变动而是监听页面内特定元素def is_registration_successful(): try: # 成功页特征出现 Youre all set 文本 Start driving 按钮 success_text driver.find_element(By.XPATH, //*[contains(text(), Youre all set)]) start_btn driver.find_element(By.XPATH, //button[contains(text(), Start driving)]) return success_text.is_displayed() and start_btn.is_displayed() except NoSuchElementException: return False if is_registration_successful(): print(✅ Registration succeeded!) # 记录本次成功数据到 results.csv with open(results.csv, a) as f: f.write(f{datetime.now()},{email},{phone},{address[city]}\n) else: print(❌ Registration failed. Check screenshot.) driver.save_screenshot(fscreenshots/fail_{int(time.time())}.png)逻辑说明is_displayed()比is_enabled()更严格它确保元素不仅存在而且在视口内可见。截图保存路径带时间戳避免覆盖。results.csv是唯一持久化输出包含时间、邮箱、手机号、城市方便你后续分析成功率与地域关联性。4. 避坑指南五个血泪经验换来的“玄学”修复方案这份脚本在真实环境中跑通远比想象中难。以下是我在某跨平台出行系统压测中踩过的五个典型坑每一条都附带可立即生效的修复代码或配置。4.1 现象Chrome 启动后立即崩溃报错DevToolsActivePort file doesnt exist原因--no-sandbox参数在某些 Linux 发行版如 Ubuntu 22.04上与新版 Chrome 冲突导致渲染进程无法初始化。解决在ChromeOptions中增加--disable-setuid-sandbox并确保以普通用户而非 root 运行chrome_options.add_argument(--disable-setuid-sandbox) # 新增此行 # 同时绝对不要用 sudo python main.py4.2 现象表单填写完成后点击“Next”按钮无响应控制台报ElementClickInterceptedException原因Uber 页面在按钮上方动态插入了一个半透明的div.overlay层用于展示加载动画或提示导致按钮被遮挡。解决改用 JavaScript 直接点击绕过 DOM 遮挡检测# 不要用 driver.find_element(...).click() next_btn driver.find_element(By.XPATH, //button[contains(text(), Next)]) driver.execute_script(arguments[0].click();, next_btn)4.3 现象验证码识别后页面卡在“Verifying your information...”10 分钟无进展原因Uber 后端对同一 IP 的注册请求有速率限制连续失败 3 次后会触发 15 分钟冷却期期间所有请求返回 429。解决在每次注册循环中加入指数退避Exponential Backoffimport time import random def exponential_backoff(attempt): base_delay 2 ** attempt # 第1次2秒第2次4秒第3次8秒 jitter random.uniform(0, 1) # 加入随机抖动 delay base_delay jitter time.sleep(delay) # 在主循环中调用 for i in range(5): if not run_registration(): exponential_backoff(i)4.4 现象geopy地理编码返回None导致地址生成失败原因Nominatim 服务对请求头User-Agent有强制要求且需声明referer。解决为geopy显式设置请求头from geopy.geocoders import Nominatim geolocator Nominatim( user_agentuber-tester, timeout10 ) # 关键设置 referer geolocator.headers.update({Referer: https://uber.com})4.5 现象上传证件照片后页面提示 “File type not supported”尽管是 JPG原因Uber 前端 JS 会读取文件的 MIME type而send_keys()上传的文件在浏览器中被识别为application/octet-stream而非image/jpeg。解决改用AutoIt或pyautogui模拟真实文件选择对话框仅 Windows# 需先 pip install pyautogui import pyautogui import time # 点击文件上传按钮触发系统对话框 upload_btn.click() time.sleep(1) # 输入文件绝对路径并回车 pyautogui.write(rC:\path\to\license.jpg) pyautogui.press(enter)注意此方案需关闭所有其他窗口确保焦点在文件对话框。Mac/Linux 用户需改用xdotool或 AppleScript脚本通常提供platform-specific-upload.py作为备选。5. 进阶技巧用脚本构建你的私有注册监控看板脚本的价值不止于单次注册而在于将其转化为可持续的监控资产。我把它部署在一台云服务器上每天凌晨 3 点自动运行 50 次生成一份 HTML 报告实时反映 Uber 司机注册流程的健康度。以下是核心实现。5.1 失败归因分类从日志中自动提取失败根因每次失败脚本会保存截图并记录failure_reason.txt。我编写了一个analyze_failures.py脚本用 OpenCV 分析截图中的文字区域匹配预设关键词import cv2 import pytesseract def classify_failure(screenshot_path): img cv2.imread(screenshot_path) # 转灰度并二值化提升 OCR 准确率 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, thresh cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY) text pytesseract.image_to_string(thresh) if reCAPTCHA in text: return captcha elif email already exists in text.lower(): return duplicate_email elif invalid phone in text.lower(): return phone_validation else: return unknown # 扫描 screenshots/ 目录统计各类失败次数 from collections import Counter failures [classify_failure(f) for f in glob(screenshots/*.png)] print(Counter(failures)) # 输出Counter({captcha: 12, duplicate_email: 3})参数说明pytesseract需提前安装 Tesseract OCR 引擎sudo apt install tesseract-ocr。Counter统计结果直接喂给监控看板形成“验证码触发率”“邮箱冲突率”等 KPI。5.2 动态代理池集成让每次请求携带不同出口 IP为规避 IP 限速我将脚本接入一个小型代理池。代理池返回的 JSON 格式为{ip: 192.168.1.100, port: 8080, user: user, pass: pass}。修改main.py中的 driver 初始化import requests def get_proxy(): resp requests.get(http://localhost:5000/get) return resp.json() proxy_info get_proxy() proxy_url fhttp://{proxy_info[user]}:{proxy_info[pass]}{proxy_info[ip]}:{proxy_info[port]} chrome_options.add_argument(f--proxy-server{proxy_url}) # 同时禁用代理认证弹窗 chrome_options.add_argument(--proxy-bypass-list-loopback)逻辑说明--proxy-bypass-list-loopback确保本地localhost请求不走代理避免调试时无法访问http://localhost:8000。代理池本身用 Flask 实现每 5 分钟轮换一次代理成本远低于商业代理服务。5.3 结果可视化用 Pandas 生成每日成功率趋势图results.csv每天追加新记录我用pandas和matplotlib生成趋势图import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(results.csv, names[timestamp, email, phone, city]) df[date] pd.to_datetime(df[timestamp]).dt.date daily_success df.groupby(date).size() plt.figure(figsize(10, 4)) daily_success.plot(kindline, markero) plt.title(Daily Uber Driver Registration Success Rate) plt.ylabel(Success Count) plt.grid(True) plt.savefig(reports/daily_success.png)提示这张图被嵌入到公司内部 Confluence 页面运维团队每天早上第一件事就是看这条曲线。当成功率跌破 70%自动触发 Slack 告警提醒前端团队检查注册页 JS 是否有异常。从那以后我每次部署新版本脚本都强制走一遍完整的“代理池 OCR 分类 趋势图生成”闭环哪怕只是本地测试。因为真正的稳定性从来不在单次成功而在千次失败中提炼出的规律。希望帮到你。本文还有配套的精品资源点击获取