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

Scrapy爬虫登录Discord失败,找不到表单元素及str无encoding属性报错

问题原因及解决方案

1. 报错核心原因

  • ValueError: No element found报错:Discord登录页是前端渲染的SPA应用,Scrapy请求拿到的初始静态HTML中没有浏览器渲染后生成的form元素,FormRequest.from_response是基于HTML里的原生form标签解析的,自然找不到对应元素。
  • AttributeError: 'str' object has no attribute 'encoding'报错:FormRequest.from_response要求传入的第一个参数是Scrapy Response对象,你错误传入了登录URL字符串,属于方法调用参数错误。

2. Discord登录逻辑说明

Discord早已不采用传统表单提交的登录方式,所有登录请求是直接调用https://discord.com/api/v9/auth/login接口完成,不需要也不应该用FormRequest.from_response构造请求。
csrf token确实存在,存储在登录页静态HTML的<script>标签内的window.__DISCORD_INITIAL_DATA__对象中,可通过正则提取:

import re
csrf_re = re.compile(r'csrf_token":"([^"]+)"')
csrf_token = csrf_re.search(response.text).group(1)

3. 修正后的登录逻辑示例

import scrapy
import re
import json

class RecruteSpider(scrapy.Spider):
    name = "Recruteur"

    def start_requests(self):
        urls = [
            'https://discord.com/login',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.login)

    def login(self, response):
        # 提取csrf token
        csrf_re = re.compile(r'csrf_token":"([^"]+)"')
        csrf_token = csrf_re.search(response.text).group(1)
        # 登录接口地址
        login_api = "https://discord.com/api/v9/auth/login"
        # 构造登录请求参数
        payload = {
            "login": "你的账号",
            "password": "你的密码",
            "undelete": False,
            "captcha_key": None,
            "login_source": None,
            "gift_code_sku_id": None
        }
        # 构造请求头
        headers = {
            "Content-Type": "application/json",
            "X-CSRFToken": csrf_token,
            "Referer": "https://discord.com/login"
        }
        yield scrapy.Request(
            url=login_api,
            method="POST",
            body=json.dumps(payload),
            headers=headers,
            callback=self.afterLogin
        )

    def afterLogin(self, response):
        res_data = json.loads(response.text)
        if "token" in res_data:
            print("登录成功,token为:", res_data["token"])
            # 后续请求携带该token即可
        else:
            print("登录失败,返回内容:", res_data)

4. 更推荐的实现方案

爬取服务器成员列表更建议使用Discord官方提供的Bot API:

  • 前往Discord开发者平台创建Bot,获取API Token
  • 将Bot加入目标服务器,授予guilds.members.read权限
  • 直接调用GET /guilds/{guild.id}/members接口获取成员列表,完全合规,不会触发账号风控,实现难度远低于模拟登录爬虫。

注意:模拟登录Discord属于违反平台用户协议的行为,频繁操作会触发验证码、账号临时封禁甚至永久封号,风险较高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:45:05