news 2026/7/4 22:59:29

Selenium免登录自动化实战:Cookie与Token原理详解及Python实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Selenium免登录自动化实战:Cookie与Token原理详解及Python实现

1. 项目概述:为什么我们需要免登录自动化?

做自动化测试或者数据抓取的朋友,肯定都遇到过登录这个“拦路虎”。每次脚本运行,都得先过登录这一关,输入账号密码、处理验证码,不仅效率低下,还容易因为登录环节的变动(比如验证码升级、登录流程调整)导致整个脚本瘫痪。更头疼的是,对于一些需要高频次、短间隔执行的任务,反复登录不仅浪费资源,还可能因为频繁请求触发系统的风控机制,导致账号被临时锁定。

这时候,“免登录”技术就成了我们的“金钥匙”。它的核心思路很简单:模拟一个已经登录成功的会话状态。想象一下,你手动登录一个网站后,浏览器会收到服务器发来的一个“通行证”(Cookie)或者一个“门禁卡”(Token)。之后你再访问网站内的其他页面,只需要出示这个“通行证”或“门禁卡”,服务器就认得你,无需再次验证身份。

在Python的Selenium自动化中,实现免登录主要就是围绕如何获取并复用这个“通行证”(Cookie)或“门禁卡”(Token)来展开的。这不仅仅是跳过登录框那么简单,它直接关系到脚本的稳定性、执行效率和维护成本。一个成熟的免登录方案,能让你的自动化脚本从“实验室玩具”升级为“生产级工具”。

2. 核心原理拆解:Cookie与Token的异同及工作逻辑

在动手之前,我们必须搞清楚我们操作的对象到底是什么。Cookie和Token虽然目标一致——维持会话状态,但它们的生成、存储和验证机制有本质区别。

2.1 Cookie:由服务器“签发”的通行证

Cookie是Web开发中最经典的会话保持机制。它的工作流程非常直观:

  1. 客户端发起登录请求:用户提交账号密码。
  2. 服务器验证并“签发”:服务器验证成功后,会在HTTP响应头中通过Set-Cookie字段,将一个或多个Cookie发送给浏览器。这个Cookie里通常包含一个唯一的会话ID(Session ID)。
  3. 浏览器自动存储与携带:浏览器会将这些Cookie保存在本地(内存或硬盘)。此后,浏览器向该域名下的任何页面发起请求时,都会自动在HTTP请求头中通过Cookie字段,将这些Cookie回传给服务器。
  4. 服务器“验票”:服务器收到请求后,解析Cookie中的会话ID,在自己的会话存储(如内存、Redis)中查找对应的会话信息。如果找到且未过期,就认为用户已登录。

在Selenium中的体现:Selenium WebDriver完全模拟了浏览器的行为。当我们使用driver.get_cookies()获取Cookie时,拿到的是浏览器当前为这个域名存储的所有Cookie键值对。而driver.add_cookie()方法,则是手动向浏览器的Cookie存储区插入一条记录,模拟浏览器收到了一个Set-Cookie指令。

注意:Cookie有作用域(Domain和Path)。你只能为当前浏览器访问的域名添加Cookie。通常,你需要先driver.get(“域名首页”)来确立域名上下文,然后再添加Cookie。

2.2 Token:自包含的“数字门禁卡”

Token(通常指JWT - JSON Web Token)是一种更现代、常用于前后端分离架构(如单页应用SPA、手机APP接口)的认证方式。它与Cookie的关键区别在于状态存储的位置

  1. 客户端发起登录请求:用户提交凭证。
  2. 服务器生成Token并返回:服务器验证成功后,生成一个Token字符串返回给客户端(通常在HTTP响应体里,如{“token”: “xxx”})。这个Token字符串本身经过加密签名,包含了用户身份、有效期等信息,服务器不需要在内存中保存这个Token
  3. 客户端主动携带Token:客户端(如浏览器中的JavaScript)需要手动将这个Token保存起来(常用localStorage或SessionStorage)。在后续请求中,需要手动将其添加到HTTP请求头中,通常是Authorization: Bearer <token>
  4. 服务器“验签”:服务器收到请求后,用预存的密钥对Token的签名进行验证,并解析其中的载荷信息。只要签名有效且未过期,就认为请求合法。

在Selenium中的体现:对于使用Token认证的网页,情况更复杂一些。因为Token通常不由浏览器自动管理。Selenium无法直接通过add_cookie来设置Token。常见的做法有两种:

  • 通过JavaScript注入:将Token写入浏览器的本地存储(LocalStorage/SessionStorage)。因为很多前端框架(如Vue、React)会从本地存储读取Token。
  • 拦截并修改请求头:这需要更高级的技巧,比如使用Selenium Wire(一个增强版Selenium)或切换到Playwright/Puppeteer,它们提供了更强大的网络请求拦截和修改能力。

选择Cookie还是Token?

  • 看目标网站的技术栈:传统Web应用多用Cookie;现代前后端分离应用、手机APP接口多用Token。
  • 看获取难度:Cookie通过浏览器开发者工具(F12 -> Application -> Cookies)很容易直接查看和复制。Token则需要到Network标签页,查看登录成功后的API响应体,或者查看后续请求的Headers。
  • 看维护成本:Cookie可能有过期时间,需要定期更新。Token也有过期时间,但因其自包含,有时可以通过刷新令牌(Refresh Token)机制来获取新的。

3. 基于Cookie的免登录实战详解

这是最常见、最直接的免登录方式,适用于绝大多数传统网站。下面我们以一个需要登录的论坛或管理系统为例,分步拆解。

3.1 第一步:手动登录并获取Cookie

在编写自动化脚本之前,我们需要先手动获取一次有效的登录Cookie。

操作流程:

  1. 打开Chrome浏览器,按F12打开开发者工具。
  2. 切换到Network(网络)标签页,勾选Preserve log(保留日志)
  3. 访问目标网站登录页,完成一次成功的登录。
  4. 在Network列表中,找到登录请求(通常是loginsignin等),查看其Response Headers(响应头),里面会有Set-Cookie字段。或者更简单的方法是:
  5. 登录成功后,刷新页面或跳转到任意需要登录的页面(如个人中心)。
  6. 在开发者工具中切换到Application(应用程序)标签页(Chrome),在左侧找到Storage -> Cookies -> [网站域名]。这里会列出所有当前域名下的Cookie。
  7. 我们需要找到那个最关键、通常名为sessionidJSESSIONIDauth_token等的Cookie。将其名称(Name)和值(Value)记录下来。注意,不要泄露这个值,它等同于你的登录密码。

实操心得:

  • 有些网站的Cookie是HttpOnly的,这意味着JavaScript无法读取它,这增强了安全性。但Selenium的get_cookies()方法仍然可以获取到,因为它在浏览器层面操作。
  • 除了namevalue,Cookie还有domainpathexpiry(过期时间戳)、secure(是否仅HTTPS)、httpOnly等属性。在后续添加时,尽量保证这些属性一致,尤其是domain

3.2 第二步:编写Selenium脚本复用Cookie

获取到Cookie后,我们就可以编写脚本,在启动浏览器后直接注入Cookie,跳过登录页面。

from selenium import webdriver import time import json # 1. 启动浏览器 driver = webdriver.Chrome() driver.implicitly_wait(10) # 设置隐式等待 try: # 2. 关键步骤:必须先访问目标域名,以确立Cookie的作用域 # 这里访问首页,不一定是登录页,只要是同域名下的任意页面即可 driver.get("https://www.target-website.com/") time.sleep(2) # 等待页面基础加载 # 3. 准备要添加的Cookie # 方式一:直接构造字典(适用于单个或少量明确知道的Cookie) login_cookie = { 'name': 'sessionid', # 替换为你的Cookie名称 'value': 'your_actual_session_id_value_here', # 替换为你的Cookie值 'domain': '.target-website.com', # 注意域名前的点,表示包括所有子域名 'path': '/', # 'expiry': 1719859200, # Unix时间戳,可选。如果已知过期时间可以加上 'httpOnly': True, # 根据实际情况设置 'secure': True # 如果网站是HTTPS,通常为True } # 方式二:从之前保存的JSON文件中加载(推荐,便于管理多个Cookie) # with open('cookies.json', 'r') as f: # cookies_list = json.load(f) # for cookie_dict in cookies_list: # driver.add_cookie(cookie_dict) # 4. 添加Cookie到浏览器 driver.add_cookie(login_cookie) # 5. 再次访问需要登录后才能看的页面 driver.get("https://www.target-website.com/user/profile") # 6. 验证是否成功 # 通过检查页面特定元素来判断,例如个人中心独有的“欢迎,XXX”字样 time.sleep(3) welcome_element = driver.find_element("css selector", ".welcome-text") if "你的用户名" in welcome_element.text: print("免登录成功!") else: print("可能未登录成功,请检查Cookie。") # 后续可以进行你的自动化操作... # driver.find_element(...).click() except Exception as e: print(f"操作过程中发生错误: {e}") # 可以在这里截图,方便排查 driver.save_screenshot('error.png') finally: # 7. 关闭浏览器 time.sleep(5) # 演示用,实际可去掉 driver.quit()

注意事项与避坑指南:

  1. domain属性的坑:这是最容易出错的地方。通过get_cookies()获取的Cookie对象,其domain字段可能类似于.target-website.com(前面有点)。在add_cookie时,domain必须和当前浏览器地址栏的域名匹配或为其父域。一个稳妥的做法是:driver.get(“基础域名”)后,添加Cookie时使用从get_cookies()获取到的原始domain值。
  2. 添加Cookie的时机:必须在driver.get()访问了同域名的页面之后才能添加。你不能在浏览器刚启动(about:blank页面)或访问一个不同域名的页面时添加。
  3. 过期问题:Cookie有生命周期。从get_cookies()获取的Cookie字典里可能包含expiry字段,它是一个Unix时间戳(秒)。如果你保存的Cookie已经过期,那么添加后也是无效的。需要定期更新Cookie文件。
  4. 安全Cookie:如果Cookie的secure属性为True,意味着它只能通过HTTPS连接传输。那么你的driver.get()的初始网址也必须是https://开头,否则添加会失败。
  5. 验证方式:不要仅凭页面URL变化判断登录成功。一定要通过查找登录后页面独有的元素(如用户名、退出按钮)来进行断言,这是自动化测试的基本素养。

3.3 第三步:Cookie的持久化与自动化更新

对于需要长期运行的脚本,手动复制Cookie太低效。我们可以将获取Cookie和注入Cookie的过程都自动化。

方案A:半自动维护Cookie池编写一个单独的“Cookie获取脚本”,定期手动运行一次(比如每周一早上),用你的账号登录并保存Cookie。

# save_cookies.py - 用于获取并保存Cookie from selenium import webdriver import json import time def get_and_save_cookies(): driver = webdriver.Chrome() driver.get("https://www.target-website.com/login") # **这里是需要手动干预的部分** print("请在浏览器中手动完成登录...") print("登录成功后,程序将在10秒后自动保存Cookie。") time.sleep(10) # 给你足够的时间手动输入密码、验证码 # 登录成功后,跳转到任意页面确保Cookie生效 driver.get("https://www.target-website.com/") # 获取所有Cookie cookies = driver.get_cookies() # 保存到文件 with open('cookies.json', 'w') as f: json.dump(cookies, f, indent=2) print(f"Cookie已保存到 cookies.json,共 {len(cookies)} 条。") driver.quit() if __name__ == '__main__': get_and_save_cookies()

然后,在你的主自动化脚本中,直接加载这个cookies.json文件。

方案B:全自动处理(适用于无复杂验证码的登录)如果登录流程简单(无图形验证码、无滑块等),可以尝试用Selenium模拟输入用户名密码来自动获取Cookie。但这需要处理登录表单,且一旦登录流程变化脚本就失效,稳定性不如直接复用Cookie。

# auto_login_and_get_cookies.py from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def auto_login(driver, username, password): driver.get("https://www.target-website.com/login") wait = WebDriverWait(driver, 10) user_input = wait.until(EC.presence_of_element_located((By.ID, "username"))) pass_input = driver.find_element(By.ID, "password") submit_btn = driver.find_element(By.CSS_SELECTOR, "button[type='submit']") user_input.send_keys(username) pass_input.send_keys(password) submit_btn.click() # 等待登录成功,例如跳转到首页或出现用户菜单 wait.until(EC.url_contains("/home") or EC.presence_of_element_located((By.CLASS_NAME, "user-menu"))) print("自动登录成功。") return driver.get_cookies()

4. 基于Token的免登录实战进阶

对于使用Token认证的现代Web应用(如Vue、React构建的管理后台),Cookie方案可能失效。因为这些应用的前端在登录后,会将Token保存在浏览器的本地存储(LocalStorage/SessionStorage)中,后续的API请求通过JavaScript在请求头中添加Authorization: Bearer <token>

Selenium的标准API无法直接操作LocalStorage,但我们可以通过执行JavaScript代码来实现。

4.1 获取Token

和获取Cookie类似,你需要手动登录一次,然后在开发者工具的Network标签页中:

  1. 找到登录成功的那个XHR/Fetch请求(通常是/api/login)。
  2. 查看其Response标签页,在响应体(Response Body)中找到Token。它通常是一个JSON对象,如{“access_token”: “eyJhbGciOi...”, “token_type”: “bearer”, “expires_in”: 3600}
  3. 复制access_token的值。

4.2 通过JavaScript注入Token

拿到Token后,我们在Selenium脚本中,先访问网站,然后通过execute_script方法将Token写入LocalStorage。

from selenium import webdriver import time driver = webdriver.Chrome() driver.implicitly_wait(10) try: # 1. 访问网站前端页面(通常是首页或登录页) driver.get("https://app.target-website.com") time.sleep(2) # 2. 准备Token(这里替换成你实际获取的Token) access_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." token_key = "auth_token" # 这个Key需要根据目标网站的前端代码确定,可能是`token`, `access_token`, `userToken`等 # 3. 通过JavaScript将Token写入LocalStorage js_code = f"window.localStorage.setItem('{token_key}', '{access_token}');" driver.execute_script(js_code) # 4. 可选:同时写入Token到SessionStorage(如果前端从这里读) # js_code_session = f"window.sessionStorage.setItem('{token_key}', '{access_token}');" # driver.execute_script(js_code_session) print("Token已注入LocalStorage。") # 5. 刷新页面,让前端JavaScript读取到新的Token并初始化登录状态 driver.refresh() time.sleep(3) # 等待前端应用重新初始化 # 6. 验证:访问一个需要认证的页面,或者检查页面元素 # 例如,前端应用可能会在Token有效后,显示用户菜单 user_menu = driver.find_element("css selector", ".user-avatar") if user_menu.is_displayed(): print("通过Token免登录成功!") else: print("Token注入可能未生效,请检查Token和Key。") except Exception as e: print(f"操作失败: {e}") driver.save_screenshot('token_error.png') finally: time.sleep(5) driver.quit()

关键点与排查技巧:

  1. 确定存储的Key:这是最大的难点。你需要查看目标网站的前端源代码(F12 -> Sources 或 直接看Network里加载的.js文件),搜索localStorage.setItemlocalStorage.getItem,看它把Token存到了哪个键(Key)下。也可以直接在开发者工具的Application -> Storage -> Local Storage里查看登录成功后有哪些条目。
  2. Token格式:确保你注入的Token字符串是完整的,包括可能有的前缀(如Bearer)。通常前端存储的是纯Token字符串,加Bearer前缀是在构造请求头时做的。
  3. 页面刷新:注入Token后,必须刷新页面driver.refresh())。因为前端应用通常在页面加载初期就从LocalStorage读取Token并初始化用户状态。不刷新的话,应用感知不到Token的变化。
  4. Token过期:和Cookie一样,Token也有有效期。你需要实现一个刷新机制,或者在Token失效时,有备用的自动登录方案。

4.3 更复杂的场景:使用Selenium Wire或Playwright

如果网站的前端逻辑非常复杂,或者Token并不是通过LocalStorage管理,而是通过更隐秘的方式(如内存变量、Service Worker),单纯的JS注入可能无效。此外,如果你想直接为所有发出的请求自动添加Authorization头,就需要更强大的工具。

  • Selenium Wire:它是Selenium的一个扩展,可以拦截和修改浏览器发出的所有请求。你可以给所有请求加上特定的Header。

    from seleniumwire import webdriver driver = webdriver.Chrome() def interceptor(request): if request.url.startswith("https://api.target-website.com"): request.headers['Authorization'] = f'Bearer {access_token}' driver.request_interceptor = interceptor driver.get("https://app.target-website.com")
  • Playwright/Puppeteer:这两个现代浏览器自动化框架在网络控制方面天生强大。以Playwright为例:

    from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch(headless=False) context = browser.new_context() # 为所有请求设置额外的HTTP头 context.set_extra_http_headers({"Authorization": f"Bearer {access_token}"}) page = context.new_page() page.goto("https://app.target-website.com") # ... 后续操作

    这种方式最为彻底和可靠,因为它是在网络层直接给请求加上了头,完全模拟了一个已登录客户端的请求行为。

5. 常见问题排查与安全实践

在实际操作中,你肯定会遇到各种各样的问题。下面是一个快速排查清单:

问题现象可能原因排查步骤与解决方案
add_cookie()失败,报错InvalidCookieDomainExceptionCookie的domain与当前浏览器页面域名不匹配。1. 确保在add_cookie前,已通过driver.get()访问了目标域名的页面。
2. 检查你构造的Cookie字典中domain字段的值。通常应该和浏览器地址栏的域名一致,或者是以.开头的父域(如.example.com匹配www.example.comapi.example.com)。
添加Cookie后,刷新页面仍然未登录1. Cookie已过期。
2. 缺少关键Cookie。
3. 网站有额外的安全校验(如IP绑定、User-Agent校验)。
1. 检查Cookie的expiry时间戳是否已过期。
2. 使用driver.get_cookies()获取登录后的完整Cookie列表,全部添加,而不是只添加一个。有时维持会话需要多个Cookie协同工作。
3. 尝试保持User-Agent一致。有些网站会校验会话与浏览器指纹的关联性。
Token注入后刷新页面,登录状态仍无效1. Token存储的Key不对。
2. Token本身已过期或无效。
3. 前端应用从其他地方读取Token(如SessionStorage、IndexedDB)。
4. 前端有复杂的初始化逻辑,需要更长的等待时间。
1. 使用F12仔细检查前端实际使用的LocalStorage Key。
2. 获取一个新的Token重试。
3. 尝试同时注入SessionStorage:sessionStorage.setItem(key, token)
4. 增加刷新后的等待时间,或通过判断特定元素出现来确认应用已就绪。
脚本在本地运行成功,但在服务器/CI环境失败1. 服务器环境无图形界面(Headless),某些网站有反爬或检测。
2. Cookie/Token在服务器环境已过期,未及时更新。
3. IP地址不同,触发风控。
1. 为Headless浏览器添加一些常见参数,如--disable-blink-features=AutomationControlled,--user-agent=...来伪装成普通浏览器。
2. 实现Cookie/Token的持久化存储和定期更新机制,确保服务器上的脚本总能拿到有效的凭证。
3. 考虑使用稳定的代理IP。
网站有滑动验证码或点选验证码这是免登录方案的天敌。1.首选:在获取Cookie/Token的环节,采用半自动方案,即手动完成一次带验证码的登录,然后长期复用凭证。
2.次选:研究验证码接口,尝试绕过(难度高,可能违法)。
3.下策:接入第三方打码平台(增加成本,稳定性依赖外部服务)。

安全与最佳实践提醒:

  1. 敏感信息保护:Cookie和Token就是你的“数字身份证”。绝对不要将包含有效Cookie/Token的脚本或配置文件上传到公开的Git仓库。使用.gitignore忽略cookies.json这类文件,或者使用环境变量、加密的配置文件来存储这些敏感信息。
  2. 遵守robots.txt与服务条款:在实施任何自动化操作前,请务必检查目标网站的robots.txt文件和服务条款。尊重网站规定,避免对服务器造成过大压力。
  3. 设置合理的等待与间隔:即使免登录了,在后续的自动化操作中(如点击、翻页、提交数据),也要加入随机延迟(time.sleep(random.uniform(1, 3))),模拟人类操作,避免被识别为机器人。
  4. 做好异常处理与日志记录:脚本中必须有完善的try...except块,对可能失败的操作(如元素找不到、网络超时)进行捕获和处理,并记录详细的日志,方便后期排查问题。
  5. 定期维护:免登录不是一劳永逸。建立定期运行“Cookie更新脚本”的机制(如每周一次),确保你的自动化任务始终有有效的凭证可用。

免登录技术是提升Selenium自动化效率和稳定性的关键一步。理解Cookie和Token的原理,熟练掌握其获取和注入方法,并能根据不同的网站架构灵活选择方案,是一个自动化工程师的必备技能。从简单的Cookie注入到复杂的Token头管理,每一步都充满了细节和“坑”,但一旦打通,你的自动化脚本将真正获得解放,能够7x24小时稳定可靠地运行。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/4 22:58:07

基于YOLO的运动员动作识别系统开发实战

1. 项目概述&#xff1a;当YOLO遇上体育竞技作为一名计算机视觉方向的开发者&#xff0c;我最近完成了一个让我自己都兴奋的项目——基于YOLO的运动员动作识别系统。这个项目最初源于我在观看篮球比赛时的一个想法&#xff1a;如果能用AI自动分析球员的投篮动作&#xff0c;那教…

作者头像 李华
网站建设 2026/7/4 22:54:24

飞牛fnOS路径穿越漏洞深度解析:从原理到实战加固

1. 项目概述&#xff1a;一次惊心动魄的飞牛fnOS安全漏洞应急响应作为一名在NAS和家庭服务器领域折腾了十多年的老玩家&#xff0c;我经历过各种系统崩溃、数据丢失&#xff0c;但像这次飞牛fnOS爆出的高危路径穿越漏洞&#xff08;Path Traversal&#xff09;这样&#xff0c;…

作者头像 李华
网站建设 2026/7/4 22:50:50

Chrome开发者工具(F12)逆向前端加密(AES)与自动化测试脚本生成

1. 初识Chrome开发者工具与前端加密每次遇到前端加密的登录表单时&#xff0c;你是不是也头疼过&#xff1f;明明用BurpSuite抓到了数据包&#xff0c;却因为数据被加密成了一串乱码而无法进行后续测试。别急&#xff0c;今天我们就用Chrome开发者工具&#xff08;F12&#xff…

作者头像 李华
网站建设 2026/7/4 22:48:52

基于YOLO系列与PySide6的口罩识别系统开发实践

1. 项目概述&#xff1a;基于YOLO系列的口罩识别系统这个口罩识别系统项目采用了YOLO系列目标检测算法的最新版本&#xff08;v5到v8&#xff09;&#xff0c;结合PySide6图形界面框架&#xff0c;实现了一个完整的端到端解决方案。我在实际部署中发现&#xff0c;相比传统Open…

作者头像 李华
网站建设 2026/7/4 22:46:45

跨区域团队API密钥统一管理:从安全风险到Taotoken实践

1. 项目概述&#xff1a;当API密钥散落全球&#xff0c;统一管理成为刚需在今天的数字化协作环境中&#xff0c;跨区域团队协同开发已成为常态。无论是硅谷的算法团队与上海的工程团队对接&#xff0c;还是柏林的创新实验室与班加罗尔的后端团队协作&#xff0c;API&#xff08…

作者头像 李华
网站建设 2026/7/4 22:44:57

如何5分钟快速上手MaiBot:打造你的专属AI群聊伙伴

如何5分钟快速上手MaiBot&#xff1a;打造你的专属AI群聊伙伴 【免费下载链接】MaiBot MaiSaka, an LLM-based intelligent agent, is a digital lifeform devoted to understanding you and interacting in the style of a real human. She does not pursue perfection, nor d…

作者头像 李华