Selenium自动化登录:利用Cookies绕过验证实现高效数据采集与测试

发布时间:2026/7/1 20:51:20
Selenium自动化登录:利用Cookies绕过验证实现高效数据采集与测试 1. 项目概述为什么我们需要绕过登录验证在自动化测试和网络数据采集的日常工作中登录验证环节常常是第一个也是最令人头疼的“拦路虎”。无论是测试一个需要登录才能访问的复杂后台功能还是爬取用户个人中心的数据手动输入账号密码不仅效率低下更无法实现流程的自动化。想象一下你写了一个自动化脚本每天凌晨定时运行去抓取某个电商网站的价格波动数据但每次运行前脚本都卡在了登录页面需要你手动介入输入验证码——这完全违背了自动化的初衷。这时候Cookies的价值就凸显出来了。它就像你进入一个高级俱乐部的会员手环。第一次进入时你需要在前台登录页面出示身份证件账号密码进行严格核验。核验通过后工作人员会给你戴上一个特殊的手环服务器下发Cookies。在接下来的几个小时里你进出俱乐部的各个区域访问网站的其他页面只需要亮出手环即可无需再次核验身份。我们的目标就是学会如何“复制”这个手环或者把一次有效的手环保存下来下次直接戴上从而绕过繁琐的“前台核验”过程。使用Selenium结合Cookies来实现这个目标是一种非常经典且实用的方案。它特别适合那些登录逻辑复杂如带有动态令牌、滑块验证等但登录后的会话维持相对简单的场景。对于测试工程师这意味着可以快速构造已登录的测试环境跳过重复的登录步骤直接对核心业务进行测试。对于开发者或数据分析师这意味着可以更稳定、更高效地获取登录后的数据。接下来我将拆解整个流程从原理到实操并附上我踩过无数坑后总结出的完整代码和避坑指南。2. 核心原理与方案选型Cookies、Session与本地存储在动手之前我们必须搞清楚我们操作的对象是什么以及为什么选择Cookies而不是其他方案。2.1 Cookies与Session的本质简单来说HTTP协议是无状态的。服务器无法自动知道两次请求是否来自同一个用户。为了解决这个问题Session会话机制被发明出来。服务器为每个用户创建一个唯一的Session ID并将这个ID通过Set-Cookie响应头发送给用户的浏览器。浏览器会把这个Session ID存储为Cookie并在后续的每一次请求中通过Cookie请求头自动携带回服务器。服务器通过比对Cookie中的Session ID和自己内存或数据库中存储的会话信息就能识别出用户身份。所以我们常说的“登录状态”在技术层面其实就是浏览器本地存储的一个或多个包含了认证信息的Cookies。我们的核心思路就是手动获取这些有效的Cookies并让Selenium驱动的浏览器在发起请求前加载它们从而让服务器认为这是一个已登录的会话。2.2 为何选择Selenium Cookies方案绕过登录验证有多种方式每种都有其适用场景直接调用登录APIPost请求最直接的方式模拟用户点击登录按钮时发送的HTTP请求。这需要分析登录表单的提交地址、参数格式可能是JSON、FormData并处理可能的加密参数、动态Token如csrf_token。优点是速度快不依赖浏览器。缺点是对复杂加密和验证码尤其是图形验证码处理困难且需要维护请求头、会话如requests.Session来保持状态。使用无头浏览器自动化登录这就是Selenium的常规用法完全模拟用户操作打开登录页、输入账号密码、点击登录。优点是可以处理任何前端复杂的登录逻辑包括验证码可结合OCR或打码平台。缺点是速度慢资源消耗大稳定性受页面加载速度和元素定位影响。使用已保存的Cookies绕过即本项目采用的方案。它结合了前两者的优点。首次登录可以采用方式1或方式2成功登录后将浏览器中的Cookies持久化保存到本地文件如JSON。后续操作时直接启动浏览器并加载这些Cookies然后访问目标页面此时浏览器已处于登录状态。这种方式完美解决了“每次都要登录”的问题特别适合需要长期维持会话或定时执行的自动化任务。为什么这个方案值得推荐稳定性高Cookies是服务器认可的“通行证”只要不过期加载后访问页面的行为与真实用户完全一致不易被反爬机制识别。复用性强一次登录长期使用直到Cookies过期。对于需要多步骤操作后才能到达目标页面的场景直接加载Cookies可以跳过所有前置步骤。兼顾灵活与效率登录过程可以手动进行处理验证码等难题也可以自动化。一旦获得Cookies后续的自动化脚本就变得非常轻量和快速。2.3 工具与环境准备工欲善其事必先利其器。以下是实现本方案所需的核心工具及其选型理由Python 3.7自动化脚本的主力语言生态丰富Selenium支持良好。Selenium 4.x浏览器自动化工具。选择4.x版本是因为其API更现代对W3C WebDriver协议支持更好并且已经稳定。浏览器驱动WebDriverChromeDriver配合Google Chrome浏览器。Chrome市场占有率最高开发者工具强大调试方便是我的首选。GeckoDriver配合Firefox浏览器。开源在某些特定场景下兼容性可能更好。说明驱动版本必须与本地安装的浏览器大版本号匹配否则会报错。这是新手最常见的坑之一。持久化存储库json模块。Cookies本质上是字典列表用JSON格式存储和读取最为简单直观。可选浏览器用户数据目录通过Selenium启动浏览器时可以指定一个真实的用户数据目录user-data-dir。这样浏览器会读取本地所有的Cookies、历史记录、扩展等。这相当于直接使用你日常使用的浏览器环境登录状态天然存在。但这种方式不够“纯净”且不利于脚本在多环境下的移植。我们本次采用更通用的“手动保存-加载”Cookies文件的方式。环境安装速查命令# 安装Selenium pip install selenium # 下载ChromeDriver需根据你的Chrome版本选择 # 访问 https://chromedriver.chromium.org/ 或使用国内镜像 # 下载后将可执行文件放在系统PATH路径下或直接在代码中指定路径。3. 实战步骤拆解从登录到Cookies持久化整个流程可以清晰地分为两大阶段获取Cookies和使用Cookies。我们先看第一阶段。3.1 第一阶段获取有效Cookies这个阶段的目标是拿到目标网站登录成功后的Cookies并将其保存到本地文件。有两种主流方法。3.1.1 方法一手动登录后自动保存推荐给初学者或处理复杂验证码这种方法最稳妥尤其当目标网站有图形验证码、滑块验证或复杂的动态加密时手动操作可以确保登录成功。步骤与代码实现import json from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time def get_cookies_manually(): 手动登录并保存Cookies # 1. 初始化浏览器驱动 # 使用Chrome并可选添加一些参数以优化体验 options webdriver.ChromeOptions() # 避免一些自动化检测非万能但有一定效果 options.add_argument(--disable-blink-featuresAutomationControlled) # 如果需要看到浏览器界面进行操作不要添加--headless参数 # options.add_argument(--headless) # 无头模式不显示浏览器窗口 driver webdriver.Chrome(optionsoptions) # 2. 访问登录页面 login_url https://www.example.com/login # 替换为你的目标登录页 driver.get(login_url) print(请在弹出的浏览器窗口中手动完成登录操作...) print(登录成功后请回到此控制台并按回车键继续。) # 3. 关键等待用户手动登录 # 这里我们通过等待用户控制台输入来判定登录完成而不是检测页面元素。 # 因为登录成功后的页面跳转是多样的。 input(确认已在浏览器中登录成功按回车键继续...) # 4. 登录成功后获取Cookies # 此时driver代表的浏览器会话已经包含了服务器下发的所有Cookies cookies driver.get_cookies() print(f成功获取到 {len(cookies)} 个Cookies) # 5. 将Cookies保存为JSON文件 with open(cookies.json, w, encodingutf-8) as f: # ensure_asciiFalse 确保中文字符正常存储 json.dump(cookies, f, ensure_asciiFalse, indent2) print(Cookies已保存至 cookies.json 文件) # 6. 可选验证一下当前页面是否确实是登录后页面 # 例如获取当前URL或页面标题 print(f当前页面标题: {driver.title}) print(f当前页面URL: {driver.current_url}) # 7. 关闭浏览器 driver.quit() print(浏览器已关闭第一阶段完成。) if __name__ __main__: get_cookies_manually()操作流程与注意事项运行上述脚本一个Chrome浏览器窗口会打开并跳转到登录页。你需要在浏览器中手动完成所有登录步骤包括输入账号密码、处理验证码等。当你看到登录成功后的页面如跳转到个人主页时回到运行脚本的命令行或控制台。按回车键脚本会立即获取当前浏览器中的所有Cookies并保存到cookies.json文件然后关闭浏览器。重要提示确保登录成功后再按回车。如果登录失败或还在登录页获取的Cookies将是无效的。3.1.2 方法二全自动登录并保存这种方法适合登录逻辑简单、无验证码或验证码可破解的网站。你需要用Selenium自动填充表单并提交。def get_cookies_automatically(): options webdriver.ChromeOptions() options.add_argument(--disable-blink-featuresAutomationControlled) driver webdriver.Chrome(optionsoptions) login_url https://www.example.com/login driver.get(login_url) # 使用显式等待确保页面元素加载完成 wait WebDriverWait(driver, 10) # 定位账号密码输入框和登录按钮需要根据目标网站实际HTML调整 # 这里只是示例请使用浏览器的开发者工具F12查看元素的实际选择器 username_input wait.until(EC.presence_of_element_located((By.ID, username))) # 假设id为username password_input driver.find_element(By.ID, password) # 假设id为password submit_button driver.find_element(By.XPATH, //button[typesubmit]) # 假设提交按钮 # 输入你的账号密码⚠️安全警告不要将真实密码硬编码在代码中 # 建议从环境变量或配置文件中读取 username_input.send_keys(your_username) password_input.send_keys(your_password) # 提交登录表单 submit_button.click() # 等待登录成功后的页面元素出现例如显示用户名的元素 # 这标志着登录成功Cookies已就绪 try: wait.until(EC.presence_of_element_located((By.CLASS_NAME, user-name))) # 示例 print(自动登录成功) except Exception as e: print(f登录后等待跳转失败: {e}) # 即使失败也尝试获取一次Cookies # 但此时的Cookies很可能无效 # 获取并保存Cookies同上 cookies driver.get_cookies() with open(cookies_auto.json, w) as f: json.dump(cookies, f, ensure_asciiFalse, indent2) driver.quit()⚠️ 安全与实操心得密码安全绝对不要将密码明文写在代码里并上传到Git等公共仓库。应该使用环境变量如os.getenv(MY_PASSWORD)或从加密的配置文件中读取。元素定位这是Selenium自动化的核心也是最容易出错的地方。务必使用浏览器的开发者工具F12仔细检查元素的id、name、class、XPath或CSS Selector。优先选择id唯一其次是用name或稳定的class。XPath功能强大但可能随页面结构微调而变化需谨慎使用。等待策略网络有延迟页面加载需要时间。绝对不要使用time.sleep(固定秒数)这是糟糕的做法。应该使用WebDriverWait配合expected_conditions进行显式等待它会在条件满足时立即继续否则超时抛出异常。这能极大提高脚本的稳定性和运行速度。4. 第二阶段加载Cookies绕过登录验证拿到cookies.json文件后我们就有了“万能钥匙”。第二阶段的目标是在新启动的浏览器会话中直接加载这些Cookies然后访问需要登录的页面此时应该直接显示已登录状态。4.1 核心代码实现def bypass_login_with_cookies(): 加载本地Cookies文件直接访问登录后页面 # 1. 初始化一个新的浏览器实例 # 注意这是一个全新的、无任何历史Cookies的会话 options webdriver.ChromeOptions() options.add_argument(--disable-blink-featuresAutomationControlled) driver webdriver.Chrome(optionsoptions) # 2. 关键步骤必须先访问目标网站的域名任意页面通常是首页 # 这是因为Cookies是有域名Domain和路径Path限制的。 # 你不能在访问google.com时加载为example.com设置的Cookies。 driver.get(https://www.example.com) # 替换为目标网站的根域名或任意页面 # 访问一下让浏览器建立起对这个域名的“上下文” time.sleep(2) # 这里可以用短时间sleep因为只是为了让浏览器建立上下文无需复杂等待 # 3. 删除当前会话中可能存在的旧Cookies保持纯净 driver.delete_all_cookies() # 4. 从JSON文件加载Cookies并添加到当前浏览器会话中 with open(cookies.json, r, encodingutf-8) as f: cookies_list json.load(f) # 读取出来是一个字典列表 for cookie in cookies_list: # 添加前可能需要处理一些属性 # 例如有些Cookie可能有‘expiry’字段它是时间戳格式 # Selenium的add_cookie方法对expiry字段有类型要求 if expiry in cookie: # 有时从文件读取的expiry是浮点数需要转换为整数 cookie[expiry] int(cookie[expiry]) # 有些网站会检查Cookie的‘sameSite’属性如果文件中有可以保留 # 使用try-except避免因无效Cookie导致整个流程中断 try: driver.add_cookie(cookie) except Exception as e: print(f添加Cookie {cookie.get(name)} 时出错: {e}) # 通常可以忽略一些非核心Cookie的错误 print(f已加载 {len(cookies_list)} 个Cookies) # 5. 刷新页面或直接跳转到需要登录才能访问的目标页面 # 刷新可以让浏览器带着新添加的Cookies重新向服务器发起请求 driver.refresh() # 或者直接访问目标地址 # target_url https://www.example.com/user/profile # driver.get(target_url) # 6. 验证是否绕过登录成功 # 等待登录后的特定元素出现例如“退出登录”按钮、用户头像等 wait WebDriverWait(driver, 10) try: # 这里以寻找“退出登录”链接为例请替换为实际目标页面的特征元素 logout_element wait.until(EC.presence_of_element_located((By.LINK_TEXT, 退出登录))) print(✅ 成功已绕过登录验证当前处于登录状态。) print(f当前用户: 可通过查找页面上的用户名元素进一步确认) # 你可以在这里开始你的后续自动化操作如点击链接、抓取数据等 # ... except Exception as e: print(❌ 失败未能检测到登录状态。可能原因) print( - Cookies已过期失效。) print( - 加载Cookies前访问的域名不正确。) print( - 网站有额外的登录状态验证如LocalStorage、Token。) print(f 错误信息: {e}) # 可以截图保存当前页面便于调试 driver.save_screenshot(login_bypass_failed.png) print(已保存错误截图: login_bypass_failed.png) # 保持浏览器打开供人工检查 print(脚本执行完毕浏览器窗口将保持打开。请手动检查页面状态。) input(按回车键退出并关闭浏览器...) driver.quit() if __name__ __main__: bypass_login_with_cookies()4.2 关键环节深度解析为什么必须先访问一次域名这是新手最容易忽略和出错的地方。浏览器的同源策略规定JavaScript以及WebDriver只能操作当前页面所在域下的Cookies。当你driver webdriver.Chrome()创建一个新驱动时它相当于打开了一个全新的、空白隐私模式的浏览器。此时它的“当前页面”是空的data:开头。如果你试图在这个状态下直接add_cookieSelenium会报错因为它不知道这个Cookie应该属于哪个域名。所以我们必须先driver.get(“目标域名”)让浏览器导航到该域名下建立起一个合法的“源”然后才能为该源添加Cookies。Cookies过期问题从浏览器导出的Cookies包含一个expiry字段表示过期时间戳Unix时间秒为单位。如果当前时间已经超过了这个时间戳那么这个Cookie就是过期的服务器将不再认可。在加载Cookie时Selenium会检查expiry如果已过期可能会添加失败或添加后无效。因此定期更新cookies.json文件是必要的。你可以在代码中添加逻辑在加载前检查并过滤掉已过期的Cookie。Session Cookie 与 持久化CookieSession Cookie 没有expiry字段生命周期仅限于浏览器会话期间。关闭浏览器即失效。这种Cookie无法持久化使用因为当你用新脚本启动浏览器时已经是一个全新的会话了。持久化Cookie 包含expiry字段在过期之前一直有效即使关闭浏览器再打开。我们保存和加载的主要是这类Cookie。除了Cookies还需要注意什么现代Web应用的身份验证机制可能非常复杂。有时仅靠Cookies是不够的。网站可能将登录状态或令牌Token存储在LocalStorage / SessionStorage 这是HTML5提供的浏览器本地存储。一些单页应用SPA如Vue.js、React.js构建的网站喜欢将JWTJSON Web Token等放在这里。如果加载Cookies后页面仍然未登录你需要检查开发者工具Application - Storage中是否有相关键值对并考虑用Selenium执行JavaScript来设置它们。IndexedDB 更复杂的客户端数据库较少用于存储简单登录态。HTTP请求头 某些API可能在每次请求时需要携带特定的Authorization头如Bearer token。实操心得 如果加载Cookies后仍然未登录请按以下步骤排查检查网络请求在加载Cookies后访问页面时打开开发者工具的Network选项卡查看第一个请求是否携带了你添加的Cookie。如果没有说明添加步骤有问题。检查登录态存储在成功登录的手动浏览器会话中打开开发者工具的Application选项卡查看Cookies、Local Storage、Session Storage下目标网站域名下存储了哪些键值对。你的自动化脚本可能需要复制所有这些信息。检查Cookie作用域确保你保存的Cookie的domain和path属性与你尝试访问的页面URL匹配。例如为.example.com设置的Cookie对sub.example.com和example.com都有效但对anotherexample.com无效。5. 完整代码封装与高级技巧将上述两个阶段的功能封装成类会更利于复用和管理。下面提供一个增强版的封装示例包含了错误处理、Cookies过期检测和自动更新逻辑。import json import time from datetime import datetime from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException, InvalidCookieDomainException class CookieLoginBypass: 使用Cookies绕过登录验证的封装类 def __init__(self, browserchrome, headlessFalse, driver_pathNone): 初始化浏览器驱动 :param browser: 浏览器类型chrome 或 firefox :param headless: 是否使用无头模式不显示浏览器界面 :param driver_path: WebDriver可执行文件的路径如果不在PATH中则需要指定 self.driver None self.browser_type browser self.headless headless self.driver_path driver_path self._init_driver() def _init_driver(self): 初始化WebDriver if self.browser_type.lower() chrome: options webdriver.ChromeOptions() if self.headless: options.add_argument(--headless) options.add_argument(--disable-blink-featuresAutomationControlled) options.add_argument(--disable-gpu) options.add_argument(--no-sandbox) # Linux环境下有时需要 options.add_argument(--disable-dev-shm-usage) # 解决共享内存问题 # 防止被检测为自动化工具更进阶的做法 options.add_experimental_option(excludeSwitches, [enable-automation]) options.add_experimental_option(useAutomationExtension, False) if self.driver_path: self.driver webdriver.Chrome(executable_pathself.driver_path, optionsoptions) else: self.driver webdriver.Chrome(optionsoptions) # 执行CDP命令隐藏webdriver属性针对一些反爬 self.driver.execute_cdp_cmd(Page.addScriptToEvaluateOnNewDocument, { source: Object.defineProperty(navigator, webdriver, { get: () undefined }); }) elif self.browser_type.lower() firefox: options webdriver.FirefoxOptions() if self.headless: options.add_argument(--headless) # Firefox的一些反检测设置相对复杂此处省略 if self.driver_path: self.driver webdriver.Firefox(executable_pathself.driver_path, optionsoptions) else: self.driver webdriver.Firefox(optionsoptions) else: raise ValueError(f不支持的浏览器类型: {self.browser_type}) # 设置全局隐式等待非必须推荐用显式等待 # self.driver.implicitly_wait(10) def manual_login_and_save(self, login_url, cookie_filecookies.json, wait_for_inputTrue): 手动登录并保存Cookies :param login_url: 登录页面地址 :param cookie_file: 保存Cookies的文件名 :param wait_for_input: 是否等待用户控制台确认 print(f正在打开登录页面: {login_url}) self.driver.get(login_url) if wait_for_input: print(\n *50) print(请在弹出的浏览器窗口中手动完成登录。) print(登录成功后在此控制台按回车键继续...) print(*50 \n) input() else: # 如果不等待输入可以设置一个固定等待时间让用户有足够时间操作 print(请在30秒内完成手动登录...) time.sleep(30) self._save_cookies(cookie_file) print(fCookies已保存至: {cookie_file}) def _save_cookies(self, cookie_file): 保存当前驱动器的Cookies到文件 cookies self.driver.get_cookies() with open(cookie_file, w, encodingutf-8) as f: json.dump(cookies, f, ensure_asciiFalse, indent2) return cookies def load_cookies_and_bypass(self, target_url, cookie_filecookies.json, domain_hintNone): 加载Cookies并访问目标页面绕过登录 :param target_url: 需要登录后才能访问的目标地址 :param cookie_file: 存储Cookies的文件名 :param domain_hint: 域名提示用于在加载Cookies前先访问该域名。如果为None则从target_url解析 :return: True表示绕过成功False表示失败 # 1. 确定用于建立上下文的域名 if domain_hint is None: # 简单地从URL中提取域名不处理复杂情况 from urllib.parse import urlparse parsed_url urlparse(target_url) domain_hint f{parsed_url.scheme}://{parsed_url.netloc} print(f步骤1: 访问域名以建立上下文: {domain_hint}) self.driver.get(domain_hint) time.sleep(2) # 短暂等待确保页面上下文建立 # 2. 清除现有Cookies self.driver.delete_all_cookies() print(步骤2: 已清除现有Cookies) # 3. 加载并添加Cookies cookies_to_load self._load_and_filter_cookies(cookie_file) print(f步骤3: 从文件加载了 {len(cookies_to_load)} 个有效Cookies) added_count 0 for cookie in cookies_to_load: try: self.driver.add_cookie(cookie) added_count 1 except InvalidCookieDomainException as e: print(f 跳过Cookie [{cookie.get(name)}]域名不匹配: {cookie.get(domain)}) except Exception as e: print(f 添加Cookie [{cookie.get(name)}] 时发生未知错误: {e}) print(f步骤4: 成功添加 {added_count} 个Cookies到浏览器) # 4. 访问目标页面 print(f步骤5: 带着Cookies访问目标页面: {target_url}) self.driver.get(target_url) # 5. 验证登录状态这里需要根据目标网站自定义验证逻辑 success self._check_login_status() if success: print(✅ 状态验证: 登录绕过成功) else: print(❌ 状态验证: 登录绕过失败。) # 可以在这里保存截图辅助调试 self.driver.save_screenshot(bypass_failed.png) return success def _load_and_filter_cookies(self, cookie_file): 加载Cookies文件并过滤掉已过期的Cookie try: with open(cookie_file, r, encodingutf-8) as f: cookies json.load(f) except FileNotFoundError: print(f错误: 未找到Cookies文件 {cookie_file}) return [] except json.JSONDecodeError: print(f错误: Cookies文件 {cookie_file} 格式无效) return [] valid_cookies [] now_timestamp int(time.time()) for cookie in cookies: # 检查过期时间 expiry cookie.get(expiry) if expiry: # 确保expiry是整数 if isinstance(expiry, float): expiry int(expiry) if expiry now_timestamp: print(f 过滤掉过期Cookie: {cookie.get(name)} (过期于 {datetime.fromtimestamp(expiry)})) continue # 检查必要的字段 if name in cookie and value in cookie: # 确保value是字符串 cookie[value] str(cookie[value]) valid_cookies.append(cookie) else: print(f 跳过无效Cookie条目: {cookie}) return valid_cookies def _check_login_status(self, timeout10): 检查当前页面是否处于登录状态 这是一个示例方法你需要根据目标网站的具体情况重写此方法 常见的检查点用户头像、退出登录链接、用户名显示元素等 # 示例1: 检查是否存在“退出登录”链接 try: wait WebDriverWait(self.driver, timeout) # 假设退出登录链接的文本包含“退出”或“Logout” logout_elements self.driver.find_elements(By.XPATH, //a[contains(text(), 退出) or contains(text(), Logout)]) if logout_elements: return True except: pass # 示例2: 检查是否存在特定的登录后页面元素通过CSS选择器 try: # 假设登录后页面有一个id为‘user-info’的div user_info self.driver.find_element(By.ID, user-info) if user_info.is_displayed(): return True except: pass # 示例3: 检查当前URL是否跳转到了登录页如果未登录访问受保护页面通常会重定向到登录页 current_url self.driver.current_url if login in current_url or signin in current_url: return False # 如果以上检查都不确定可以返回False或者根据需求调整 # 更稳健的做法是提供一个可配置的检查元素列表给用户 print(警告: 登录状态检查逻辑未明确匹配请根据目标网站自定义 _check_login_status 方法。) return False # 默认认为失败保守策略 def quit(self): 关闭浏览器驱动 if self.driver: self.driver.quit() print(浏览器已关闭) # 使用示例 if __name__ __main__: # 实例化工具类 helper CookieLoginBypass(browserchrome, headlessFalse) # 场景A: 首次运行手动登录并保存Cookies # helper.manual_login_and_save(https://www.example.com/login, my_cookies.json) # helper.quit() # 场景B: 后续运行使用保存的Cookies直接访问个人中心 success helper.load_cookies_and_bypass( target_urlhttps://www.example.com/user/dashboard, cookie_filemy_cookies.json ) if success: print(可以开始执行后续自动化任务了...) # 例如抓取数据 # page_source helper.driver.page_source # 或者点击某个按钮 # button helper.driver.find_element(By.XPATH, //button[text()下载]) # button.click() # time.sleep(5) else: print(登录绕过失败可能需要重新获取Cookies。) # 保持浏览器打开以便观察 input(按回车键结束程序并关闭浏览器...) helper.quit()6. 常见问题、排查技巧与进阶思考即使按照上述步骤操作你仍然可能会遇到各种问题。下面是我在实践中总结的常见问题排查清单和进阶技巧。6.1 常见问题速查表问题现象可能原因排查与解决方案add_cookie报错InvalidCookieDomainException添加Cookie时浏览器当前页面的域名与Cookie的domain属性不匹配。1. 确保在add_cookie前先用driver.get()访问了Cookie所属的域名或父域名。2. 检查cookies.json中Cookie的domain字段值。通常以.开头如.example.com的Cookie对该域名及其子域名都有效。加载Cookies后访问页面仍然跳转到登录页1. Cookies已过期。2. 缺少关键Cookie如Session ID。3. 登录状态还依赖于LocalStorage等其他存储。4. 网站有额外的安全校验如IP绑定、User-Agent校验。1. 检查Cookies的expiry时间戳并更新文件。2. 对比手动登录成功后的Cookies列表与保存的列表看是否漏掉了某个关键的Cookie通常name值包含sess,session,token,auth等。3. 打开开发者工具在Application-Storage下查看Local Storage和Session Storage尝试用driver.execute_script(“window.localStorage.setItem(‘key’, ‘value’);”)来设置。4. 尝试在Selenium中设置与手动登录时一致的User-Agent。Selenium被网站检测到即使有Cookies也无法登录网站使用了反爬或反自动化技术能检测到Selenium驱动的浏览器特征。1. 使用更隐蔽的选项如本文代码中的--disable-blink-featuresAutomationControlled和CDP命令。2. 使用undetected-chromedriver等第三方库它能更好地隐藏自动化特征。3. 尝试更换浏览器如从Chrome换到Firefox或使用更老/更稳定的驱动版本。4. 终极方案考虑使用Playwright或Puppeteer它们在某些场景下比Selenium更隐蔽。手动可以登录但自动化脚本无法定位登录按钮或输入框1. 页面元素加载慢脚本执行太快。2. 元素在iframe框架内。3. 元素属性是动态生成的。1.永远使用显式等待WebDriverWait而不是time.sleep。2. 检查页面是否存在iframe需要使用driver.switch_to.frame()切换到对应iframe后才能操作内部元素。3. 使用更稳定的定位方式如结合多个属性的XPath//input[name‘username’ and type‘text’]或使用相对定位。Cookies文件加载失败JSON解码错误Cookies文件格式损坏或被意外修改。1. 检查文件内容是否为合法的JSON格式可以使用在线JSON校验工具。2. 确保文件编码是UTF-8。3. 重新运行一次manual_login_and_save生成新的文件。6.2 进阶技巧与扩展1. 多账号Cookies管理如果你需要管理多个账号可以为每个账号单独保存一个Cookies文件如cookies_user1.json,cookies_user2.json。在加载时根据任务需求选择对应的文件即可。2. 定时更新Cookies写一个调度任务如使用schedule库或操作系统的crontab定期例如在Cookies过期前一周运行一次“自动登录并保存Cookies”的脚本以更新文件确保长期有效。3. 结合API登录对于验证码复杂的网站可以尝试“半自动”方案手动登录部分通过调用第三方打码平台的API来解决验证码识别其余步骤输入账号密码、提交由Selenium完成。这样既避免了纯手动操作的繁琐又解决了纯自动化的识别难题。4. 处理OAuth等第三方登录如果网站使用微信、GitHub等第三方登录流程会复杂很多。通常的思路是手动完成一次第三方授权然后保存授权后的主站Cookies。因为第三方授权成功后会回调回原网站并设置登录态Cookie。后续加载这个主站Cookie即可。注意第三方平台如微信本身可能有更严格的反自动化机制。5. 分布式与持久化在大型爬虫或测试系统中可以将有效的Cookies存储到数据库如Redis中并为其打上“有效期”、“所属账号”、“最后使用时间”等标签。多个爬虫节点或测试机可以从数据库中申请可用的Cookies来使用实现资源共享和负载均衡。绕过登录验证只是自动化工作的起点。掌握了Cookies这把钥匙你就能打开那些需要身份认证才能访问的数据和功能之门。这套方法的核心思路——“状态保存与恢复”——在软件测试、数据采集乃至机器人流程自动化RPA中都有着广泛的应用。在实际操作中耐心和细致的观察多利用浏览器的开发者工具是成功的关键。每一个网站都有其独特性没有放之四海而皆准的代码但有了本文提供的框架和排查思路你完全有能力去应对绝大部分的挑战。