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

Scrapy跨跳转会话认证失效,爬取需登录目录站点隔条目掉登录态

问题根因拆解

你目前的实现确实符合Scrapy官方文档的基础登录流程,但日志中暴露了两个核心的认证态丢失原因:

1. 跨二级域的Cookie隔离

登录成功后,你从www.example.com域拿到的有效认证Cookie是ASP.NET_SessionId=lgvbj33sbnlbsyp4hpe5jhxf,这个Cookie的作用范围被严格限制在www.example.com域下。
你的目录条目链接指向不带www的example.com域,Scrapy默认的Cookie中间件会遵循浏览器同源规则,不会自动把www.example.com的Cookie发送给不带www的同顶级域站点。
从日志可以看到直接的验证证据:

[scrapy.downloadermiddlewares.cookies] DEBUG: Received cookies from: <200 https://example.com/directory/members/123640>
Set-Cookie: ASP.NET_SessionId=iyeclhcbqwxbfycplifedyxu; path=/; HttpOnly; SameSite=Lax

这是服务器给完全未携带登录Cookie的匿名访客下发的全新会话标识,证明服务器根本没识别到你之前的登录状态。

2. SSO跳转流程的Cookie不同步

站点采用的是跨域SSO认证逻辑,需要经过主站登录→SSO服务校验→认证Cookie同步到所有关联二级域的完整流程,才能保持跨域访问的认证态。
你目前的流程是主站登录完成后,直接跳到不带www的目录站,跳过了SSO服务的校验步骤,导致所有二级域的Cookie没有完成同步,访问任意跨域条目时都会触发登录态校验失败。
从日志可以看到请求SSO服务时的Cookie拼接混乱问题:

[scrapy.downloadermiddlewares.cookies] DEBUG: Sending cookies to: <GET https://webservice.example.com/wcasso/SsoV1/CheckLoggedIn?otherParams>
Cookie: ASP.NET_SessionId=c2e3avij54xfpn4a5ofl4xdt;sso_signin=user_id=user_id_code;ASP.NET_SessionId=iyeclhcbqwxbfycplifedyxu

三个二级域的SessionId被无序拼接,SSO服务根本无法匹配到有效的登录用户身份。

修复方案

1. 关闭Scrapy的域名级Cookie隔离

Scrapy默认会为每个独立域名维护独立的Cookie存储,如果你确认当前爬取的www.example.com、example.com、webservice.example.com属于同一套SSO认证体系,直接在settings.py中配置全局共享Cookie:

# 开启全局共享Cookie,所有请求共用同一份Cookie存储
COOKIES_JAR = 'shared_auth_jar'

配置后所有域的Cookie会统一存储,不再出现跨域无法携带认证信息的问题。

2. 补全SSO流程的跳转链路

在登录成功后,先主动触发SSO校验流程,等所有二级域的Cookie同步完成后,再开始抓取目录列表,对应代码调整如下:

def parse_after_login(self, response):
    if b"Member Section" not in response.body:
        self.log("Login failed")
        return
    self.log("Login success, starting SSO cookie sync")
    # 先请求SSO校验地址,触发全链路Cookie同步
    yield scrapy.Request(
        url="https://webservice.example.com/wcasso/SsoV1/CheckLoggedIn",
        callback=self.start_crawl_directory
    )

def start_crawl_directory(self, response):
    # 跟随SSO跳转完成Cookie同步后,再开始抓取目录页
    for url in PAGES:
        yield scrapy.Request(url, callback=self.parse_directory_page)

3. 强制携带有效认证Cookie(兜底方案)

如果调整全局Cookie后仍有跨域问题,可以写一个简单的下载中间件,在每次发起请求时强制把登录成功拿到的有效认证Cookie带上:

class ForceAuthCookieMiddleware:
    def process_request(self, request, spider):
        # 从第一次登录成功的响应中提取有效Cookie,替换无效的域专属Cookie
        valid_auth_cookies = {
            'ASP.NET_SessionId': 'lgvbj33sbnlbsyp4hpe5jhxf',
            'sso_signin': 'user_id=user_id_code'
        }
        request.cookies.update(valid_auth_cookies)
        return None

在settings.py中将这个中间件加入下载链路即可生效。

无效操作澄清
  • 你之前配置的CONCURRENT_REQUESTS = 1并不是解决这个问题的核心,哪怕高并发场景下,只要Cookie存储是打通的,就不会出现认证态丢失
  • 你提到的__RequestVerificationToken确实不会影响这个问题,这个参数是用于防护CSRF跨站攻击的,和长期认证态的保持没有直接关联

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 07:06:05