如何获取任何 Discord 服务器的成员总数?

ozg*_*zer 4 api axios discord puppeteer

我正在尝试构建一个抓取脚本来获取一堆 Discord 服务器的全部成员。实际上,我是用 Puppeteer 这样做的,如下所示,但我认为我的 IP 地址已被禁止,因为即使邀请链接有效,我也会收到来自 Discord 的“邀请无效”错误。

我的问题是,Discord 是否有 API 可以获取任何服务器的成员总数?或者是否有用于此目的的第三方库?或者有其他方法吗?

const puppeteer = require('puppeteer')

const discordMembers = async ({ server, browser }) => {
  if (!server) return

  let totalMembers

  const page = await browser.newPage()

  try {
    await page.goto(`https://discord.com/invite/${server}`, {
      timeout: 3000
    })

    const selector = '.pill-qMtBTq'
    await page.waitForSelector(selector, {
      timeout: 3000
    })
    const totalMembersContent = await page.evaluate(selector => {
      return document.querySelectorAll(selector)[1].textContent
    }, selector)

    if (totalMembersContent) {
      totalMembers = totalMembersContent
        .replace(/ Members/, '')
        .replace(/,/g, '')
      totalMembers = parseInt(totalMembers)
    }
  } catch (err) {
    console.log(err.message)
  }

  await page.close()

  if (totalMembers) return totalMembers
}

const asyncForEach = async (array, callback) => {
  for (let i = 0; i < array.length; i++) {
    await callback(array[i], i, array)
  }
}

const run = async () => {
  const browser = await puppeteer.launch({
    headless: true,
    args: ['--no-sandbox']
  })

  const servers = ['tQp4pSE', '3P5K3dzgdB']

  await asyncForEach(servers, async server => {
    const members = await discordMembers({ server, browser })
    console.log({ server, members })

    // result
    // { server: 'tQp4pSE', members: 57600 }
    // { server: '3P5K3dzgdB', members: 159106 }
  })

  await browser.close()
}

run()
Run Code Online (Sandbox Code Playgroud)

更新:2022 年 3 月 22 日

感谢 @Vaviloff 的回答,我们实际上可以访问 Discord 的私有 API,但问题是它只能通过浏览器访问。我收到Request failed with status code 400来自 Axios 的问题。是 CORS 问题吗?我们如何在 Node.js 应用程序中获取结果?

const axios = require('axios')

const discordMembers = async ({ server }) => {
  try {
    const apiResult = await axios({
      data: {},
      method: 'get',
      url: `https://discord.com/api/v9/invites/${server}?with_counts=true&with_expiration=true`
    })
    console.log(apiResult)
  } catch (err) {
    console.log(err)
  }
}

discordMembers({ server: 'tQp4pSE' })
Run Code Online (Sandbox Code Playgroud)

Vav*_*off 10

许多现代 Web 应用程序都有自己的内部 API。通常,您可以通过使用 Devtools 中的“网络”选项卡(按 Fetch/XHR 类型过滤)来发现前端向其发出请求:

内部API请求图像

当然,此类 API 端点可以随时更改,但通常会持续很长时间,并且是一种相当方便的抓取方式

目前 Discord 使用此 URL 进行基本实例描述:

https://discord.com/api/v9/invites/tQp4pSE?with_counts=true&with_expiration=true
Run Code Online (Sandbox Code Playgroud)

通过访问它,您可以获得所需的数据:
与内部 API 不一致的实例统计信息


更新
为了使您的代码正常工作,请不要在请求中发送任何数据:

const apiResult = await axios({
  method: 'get',
  url: `https://discord.com/api/v9/invites/${server}?with_counts=true&with_expiration=true`
})
Run Code Online (Sandbox Code Playgroud)

  • 当然可以,查看更新 (2认同)