You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Selenium爬取需身份认证站点时如何存储登录会话

问题原因及修复方案

代码存在的核心问题

  1. 多余的Cookie操作覆盖原有有效会话:你使用的是同一个Firefox驱动实例,登录完成后会话Cookie会自动保存在驱动的会话存储中,不需要手动调用get_cookies再add_cookie,该操作可能导致有效Cookie被覆盖、属性异常,反而破坏登录态。
  2. 未等待登录流程完全落地就获取Cookie:输入验证码按下回车后,站点需要完成后端校验、返回会话Cookie、跳转登录后页面的流程,你立即执行Cookie读取操作时,核心会话Cookie还未写入浏览器存储,拿到的Cookie不包含有效身份凭证。
  3. XPath表达式存在语法隐患:你编写的class匹配规则错误使用了HTML转义符",Python字符串中单引号包裹的内容可直接使用双引号,不需要转义,该问题可能导致验证元素匹配失败,登录流程未完整执行。
  4. (跨驱动复用Cookie场景特有问题)添加Cookie前未访问对应域名:如果你后续要实现重启驱动复用Cookie的功能,Selenium要求添加Cookie前,驱动必须先访问过Cookie所属域名的任意页面,否则会因为域名校验不通过添加失败。

修复代码示例

同驱动直接访问登录后页面(最简修复)

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver import Firefox

driver = Firefox()

def logon(drvr):
    drvr.get('https://www.site/to/scrape/logon')
    wait = WebDriverWait(drvr, 10)
    elem = wait.until(EC.presence_of_element_located((By.NAME, 'memberId')))
    elem.send_keys('xxxx', Keys.RETURN)
    elem = wait.until(EC.presence_of_element_located((By.NAME, 'password')))
    elem.send_keys('xxxx', Keys.RETURN)
    # 修复XPath引号问题
    elem = wait.until(EC.presence_of_element_located((By.XPATH, '//a[@class="sub-label font-narrow"]')))
    ver = elem.get_attribute('aria-label')
    if ' '.join(ver.split()) == 'phone number ending in 1 3 6 1':
        elem.click()
    value = input('Enter security code: ')
    elem = wait.until(EC.presence_of_element_located((By.NAME, 'inputValue')))
    elem.send_keys(value, Keys.RETURN)
    # 新增:等待登录完成,确认会话Cookie生效
    # 替换为你登录成功后跳转的URL特征,或者等待登录后才存在的页面元素
    wait.until(EC.url_contains('site.com/home'))

def main(drvr):
    # 移除多余的Cookie操作,直接访问受保护页面
    drvr.get('https://www.site/behind/logon')
    print(drvr.page_source[:1000])

logon(driver)
main(driver)

跨驱动持久化复用登录态(可选方案)

如果需要重启浏览器仍保留登录状态,可使用如下方案序列化存储Cookie:

import json
import time

# 登录完成后保存Cookie到本地
def save_cookies(drvr, path='site_cookies.json'):
    with open(path, 'w', encoding='utf-8') as f:
        json.dump(drvr.get_cookies(), f, ensure_ascii=False, indent=2)

# 新启动驱动后加载本地Cookie
def load_cookies(drvr, path='site_cookies.json', target_domain_root='https://www.site/'):
    # 必须先访问目标站点任意页面,才能添加对应域名的Cookie
    drvr.get(target_domain_root + '404')
    with open(path, 'r', encoding='utf-8') as f:
        cookies = json.load(f)
    for cookie in cookies:
        # 过滤过期Cookie
        if 'expiry' in cookie and cookie['expiry'] < time.time():
            continue
        drvr.add_cookie(cookie)
    # 添加完成后再访问受保护页面
    drvr.get('https://www.site/behind/logon')

非Cookie存储会话的排查方案

如果确认Cookie正确仍无法登录,可按以下顺序排查其他会话存储方式:

  • 排查LocalStorage/SessionStorage:打开浏览器F12控制台「应用」标签,查看对应域名下的Local Storage、Session Storage内容,多数单页应用会将JWT身份令牌、会话标识存在此处。Selenium可通过执行JS读写存储内容:drvr.execute_script('return window.localStorage.getItem("token_key")')、drvr.execute_script('window.localStorage.setItem("key", "value")')。
  • 排查自定义请求头:在F12「网络」标签对比登录前后访问受保护页面的请求头差异,部分站点会使用X-Auth-Token、Authorization等自定义头传递身份凭证,可通过Selenium的请求拦截功能添加对应头字段。
  • 排查设备指纹绑定:部分站点会将会话和浏览器User-Agent、屏幕分辨率、WebGL指纹等设备特征绑定,重启驱动时需保持启动参数、浏览器属性和登录时完全一致。
  • 排查Cookie属性限制:检查Cookie的Secure、SameSite、HttpOnly属性,确保访问协议、域名和Cookie要求的规则匹配,例如Secure标识的Cookie只能在HTTPS协议下传递。

内容的提问来源于stack exchange,提问作者malonn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 17:21:01