我目前正在尝试学习网络抓取,并决定抓取一些不和谐的数据。代码如下:
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 使用 limit
、before
和 after
参数实现分页,其中:
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/