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
相关产品推荐
相关产品推荐

