python - 使用python在discord上抓取数据

标签 python web-scraping discord

我目前正在尝试学习网络抓取,并决定抓取一些不和谐的数据。代码如下:

import requests
import json

def retrieve_messages(channelid):
    num=0
    headers = {
        'authorization': 'here we enter the authorization code'
    }
    r = requests.get(
        f'https://discord.com/api/v9/channels/{channelid}/messages?limit=100',headers=headers
        )
    jsonn = json.loads(r.text)
    for value in jsonn:
        print(value['content'], '\n')
        num=num+1
    print('number of messages we collected is',num)

retrieve_messages('server id goes here')

问题:当我尝试在此处更改限制时 messages?limit=100 显然它只接受 0 到 100 之间的数字,这意味着我可以获得的最大消息数是 100。我试过了例如,将此数字更改为 900 以抓取更多消息。但随后我收到错误 TypeError: string indices must be integers

关于如何获取 channel 中所有消息的任何想法?

非常感谢您的阅读!

最佳答案

返回一堆记录的 API 几乎总是限于一定数量的项目。 否则,如果请求大量项目,API 可能会因内存不足而失败。

为此,大多数 API 使用 limitbeforeafter 参数实现分页,其中:

  • limit:告诉您要获取多少条消息
  • before: 获取消息ID之前的消息
  • after:获取此消息ID之后的消息

Discord API 也不异常(exception),因为 documentation告诉我们。 方法如下:

首先,您需要多次查询数据。 为此,您可以使用 while 循环。 确保添加一个 if 条件,以防止循环无限期地运行 - 我添加了一个检查是否还有任何消息。

    while True:
        # ... requests code
        jsonn = json.loads(r.text)
        if len(jsonn) == 0:
            break
        
        for value in jsonn:
            print(value['content'], '\n')
            num=num+1

定义一个变量,其中包含您获取的最后一条消息并保存您已打印的最后一条消息 ID

        
def retrieve_messages(channelid):
    last_message_id = None

    while True:
        # ...
        
        for value in jsonn:
            print(value['content'], '\n')
            last_message_id = value['id']
            num=num+1

现在,在第一次运行时,last_message_id 为 None,在随后的请求中,它具有您打印的最后一条消息。

用它来构建你的查询

    while True:
        query_parameters = f'limit={limit}'
        if last_message_id is not None:
            query_parameters += f'&before={last_message_id}'

        r = requests.get(
            f'https://discord.com/api/v9/channels/{channelid}/messages?{query_parameters}',headers=headers
            )
        
        # ...

注意:discord服务器首先给你最新消息,所以你必须使用before参数

这是您的代码的完整示例

import requests
import json

def retrieve_messages(channelid):
    num = 0
    limit = 10

    headers = {
        'authorization': 'auth header here'
    }

    last_message_id = None

    while True:
        query_parameters = f'limit={limit}'
        if last_message_id is not None:
            query_parameters += f'&before={last_message_id}'

        r = requests.get(
            f'https://discord.com/api/v9/channels/{channelid}/messages?{query_parameters}',headers=headers
            )
        jsonn = json.loads(r.text)
        if len(jsonn) == 0:
            break

        for value in jsonn:
            print(value['content'], '\n')
            last_message_id = value['id']
            num=num+1

    print('number of messages we collected is',num)

retrieve_messages('server id here')

关于python - 使用python在discord上抓取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67793922/

相关文章:

python - XOR bin 值时缺少 0

python - 如何将 Google Chrome 扩展与 Selenium 结合使用?

discord - 启动 Discord 时出现问题 (Fedora 35)

python - Blender - 从 python 脚本打开并解析 .blend 文件

python - PYQT - 如何使用取消按钮取消 GUI 中的循环?

python - 如何在 python 脚本末尾启动 REPL?

java - JSoup 不加载整个 HTML

python - Scrapy ItemLoader 项目组合

javascript - 如何使 if (message.content.startsWith ('' )) 检测两件事

python - 如何使 pyodbc 输出更具可读性/更好?