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

使用Scrapy爬取需登录网站时出现403错误,代码无法运行求助

分析与修复Scrapy登录返回403的问题

你的代码返回403主要是反爬机制拦截和代码本身的几个细节问题导致的,以下是具体分析和修复方案:

1. 验证码字段未正确处理

代码里g-recaptcha-response填了空格,而Classmates.com的登录页面启用了reCAPTCHA验证,这个字段需要真实有效的验证码响应值才能通过验证。空值或无效值会直接触发403拦截。

临时测试方案:手动在浏览器完成验证码,然后从浏览器的登录请求中复制g-recaptcha-response的真实值填入formdata;生产环境则需要对接验证码识别服务。

2. 默认User-Agent易被识别

Scrapy默认的User-Agent格式为Scrapy/version (+https://scrapy.org),很容易被反爬系统标记为爬虫。需要替换为真实浏览器的User-Agent。

修复方法:
在项目的settings.py中全局设置:

USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'

或者在请求中手动指定:

def start_requests(self):
    yield scrapy.Request(
        self.login_url,
        callback=self.login,
        headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'}
    )

3. start_urls初始化不符合规范

你在__init__里把start_urls设为字符串,但Scrapy的start_urls预期是列表类型。虽然重写start_requests方法后不会直接触发错误,但建议修正以符合代码规范:

def __init__(self):
    self.start_urls = [self.login_url]

4. FormRequest表单定位可能出错

FormRequest.from_response默认会自动查找页面第一个表单,如果页面存在多个表单,可能会定位错误。可以通过formid参数明确指定登录表单:

yield FormRequest.from_response(
    response,
    formid='login-form',  # 精准匹配登录表单的id属性
    formdata={
        '_csrf': token,
        'successUrl': '',  # 这里应该是空字符串,而非空格
        'g-recaptcha-response': '真实验证码响应值',
        'emailOrRegId': 'user@mail.com',
        'password': 'some password',
        'rememberme': 'yes'
    },
    callback=self.start_scraping,
    headers={'Referer': self.login_url}  # 手动添加Referer头,模拟真实请求逻辑
)

5. 显式传递Cookie增强请求真实性

部分网站会校验Cookie的连贯性,虽然FormRequest.from_response默认会处理,但显式传递第一次访问登录页面获取的Cookie,可以降低被拦截概率:

def login(self, response):
    token = response.css("form[id*=login-form] input[name*=csrf]::attr(value)").extract_first()
    yield FormRequest.from_response(
        response,
        formid='login-form',
        formdata={...},  # 你的表单数据
        callback=self.start_scraping,
        cookies=response.cookies  # 显式传递Cookie
    )

修复后的完整代码示例

import scrapy
from scrapy import Spider
from scrapy.http import FormRequest


class HiddenDataLoginSpider(Spider):
    name = 'images'
    login_url = 'https://secure.classmates.com/auth/login'

    def __init__(self):
        self.start_urls = [self.login_url]

    def start_requests(self):
        yield scrapy.Request(
            self.login_url,
            callback=self.login,
            headers={
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
            }
        )

    def login(self, response):
        token = response.css("form[id*=login-form] input[name*=csrf]::attr(value)").extract_first()
        # 注意:g-recaptcha-response需要替换成真实的验证码响应值
        yield FormRequest.from_response(
            response,
            formid='login-form',
            formdata={
                '_csrf': token,
                'successUrl': '',
                'g-recaptcha-response': 'YOUR_RECAPTCHA_RESPONSE',
                'emailOrRegId': 'user@mail.com',
                'password': 'some password',
                'rememberme': 'yes'
            },
            callback=self.start_scraping,
            headers={
                'Referer': self.login_url,
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
            }
        )

    def start_scraping(self, response):
        # 先检查登录状态
        print("响应状态码:", response.status)
        print("页面标题:", response.css('title::text').get())
        print("页面h3元素:", response.css('h3').getall())

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 23:45:38