如何获得任何 Discord 服务器的总成员数?
How to get total member count of any Discord server?
我正在尝试构建一个抓取脚本来获取一堆 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()
更新:2022 年 3 月 22 日
感谢@Vaviloff 的回答,我们实际上可以访问 Discord 的私有 API,但问题是它只能通过浏览器访问。我从 Axios 收到 Request failed with status code 400
问题。这是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' })
许多现代网络应用程序都有自己的内部 APIs。通常,您可以通过使用 Devtools 中的“网络”选项卡(按 Fetch/XHR 类型过滤)来发现前端向它发出请求:
这样的 API 端点当然可以随时更改,但通常会持续很长时间并且是一种相当方便的抓取方式
目前 Discord 使用此 URL 进行基本实例描述:
https://discord.com/api/v9/invites/tQp4pSE?with_counts=true&with_expiration=true
通过访问它,您可以获得所需的数据:
更新
为了使您的代码正常工作,请不要在请求中发送任何数据:
const apiResult = await axios({
method: 'get',
url: `https://discord.com/api/v9/invites/${server}?with_counts=true&with_expiration=true`
})
我正在尝试构建一个抓取脚本来获取一堆 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()
更新:2022 年 3 月 22 日
感谢@Vaviloff 的回答,我们实际上可以访问 Discord 的私有 API,但问题是它只能通过浏览器访问。我从 Axios 收到 Request failed with status code 400
问题。这是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' })
许多现代网络应用程序都有自己的内部 APIs。通常,您可以通过使用 Devtools 中的“网络”选项卡(按 Fetch/XHR 类型过滤)来发现前端向它发出请求:
这样的 API 端点当然可以随时更改,但通常会持续很长时间并且是一种相当方便的抓取方式
目前 Discord 使用此 URL 进行基本实例描述:
https://discord.com/api/v9/invites/tQp4pSE?with_counts=true&with_expiration=true
通过访问它,您可以获得所需的数据:
更新
为了使您的代码正常工作,请不要在请求中发送任何数据:
const apiResult = await axios({
method: 'get',
url: `https://discord.com/api/v9/invites/${server}?with_counts=true&with_expiration=true`
})