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

Discord.py实现Codeforces赛前24小时提醒:如何获取网站数据?

从Codeforces获取赛事数据实现Discord机器人提醒功能

你不用纠结JavaScript解析页面的问题,Codeforces提供了官方公开API,直接用Python就能拿到赛事数据,完全不用处理前端渲染的JS内容。下面是具体实现步骤:

1. 调用Codeforces赛事列表API

Codeforces的contest.list接口可以返回所有公开赛事的信息,包括即将开始的比赛。接口地址是https://codeforces.com/api/contest.list?gym=false(gym=false表示排除训练赛,只拿公开竞赛)。

用Python的requests库请求这个接口:

import requests

def get_codeforces_contests():
    url = "https://codeforces.com/api/contest.list?gym=false"
    try:
        response = requests.get(url)
        response.raise_for_status()  # 捕获请求错误
        data = response.json()
        if data["status"] == "OK":
            return data["result"]  # 返回赛事列表数组
        else:
            print(f"API返回错误: {data['comment']}")
            return []
    except Exception as e:
        print(f"请求失败: {str(e)}")
        return []

2. 筛选出24小时内即将开始的比赛

接口返回的每个赛事对象里,startTimeSeconds是比赛开始的Unix时间戳,我们可以把它和当前时间对比,筛选出时间差在24小时(86400秒)以内的比赛,同时只取phase为BEFORE(还未开始)的赛事。

示例代码:

import time
from datetime import datetime, timedelta

def get_upcoming_contests(contests):
    upcoming = []
    now = time.time()
    twenty_four_hours = 86400  # 24小时的秒数
    
    for contest in contests:
        if contest["phase"] != "BEFORE":
            continue  # 跳过已开始或已结束的比赛
        
        start_time = contest["startTimeSeconds"]
        time_diff = start_time - now
        
        if 0 < time_diff <= twenty_four_hours:
            # 提取你需要的字段(对应你说的高亮数据)
            contest_info = {
                "name": contest["name"],
                "start_time": datetime.fromtimestamp(start_time).strftime("%Y-%m-%d %H:%M:%S UTC"),
                "duration": str(timedelta(seconds=contest["durationSeconds"])),
                "link": f"https://codeforces.com/contest/{contest['id']}"
            }
            upcoming.append(contest_info)
    
    return upcoming

3. 整合到discord.py机器人实现提醒

用discord.py的tasks扩展做定时任务,比如每隔1小时检查一次赛事,发现符合条件的就发送到指定频道:

import discord
from discord.ext import commands, tasks

intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix="!", intents=intents)

# 替换成你的提醒频道ID
REMINDER_CHANNEL_ID = 123456789012345678

@bot.event
async def on_ready():
    print(f"Logged in as {bot.user}")
    check_contests.start()  # 启动定时任务

@tasks.loop(hours=1)
async def check_contests():
    contests = get_codeforces_contests()
    upcoming = get_upcoming_contests(contests)
    
    if not upcoming:
        return
    
    channel = bot.get_channel(REMINDER_CHANNEL_ID)
    if not channel:
        print("提醒频道不存在")
        return
    
    # 构造提醒消息
    embed = discord.Embed(title="📅 Codeforces比赛即将开始!", color=discord.Color.blue())
    for contest in upcoming:
        embed.add_field(
            name=contest["name"],
            value=f"开始时间:{contest['start_time']}\n时长:{contest['duration']}\n[前往比赛]({contest['link']})",
            inline=False
        )
    
    await channel.send(embed=embed)

# 替换成你的机器人Token
bot.run("YOUR_BOT_TOKEN")

注意事项

  • 不要频繁调用API,Codeforces的API限制是每秒最多1次请求,上面的定时任务1小时检查一次完全符合要求
  • 记得安装依赖:pip install requests discord.py
  • 机器人需要有发送消息到目标频道的权限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:56:13