如何让Discord Bot提取消息内容并转为可复用变量?
问题解决与代码修正
先明确你代码里的几个核心问题,以及对应的解决办法:
message.content()写法错误:message.content是字符串属性,不是可调用方法,必须去掉括号,写成message.content。- 未剥离命令前缀:用户发送的消息是
/channel 链接格式,直接取message.content会包含/channel前缀,必须剥离这部分才能拿到纯净的目标URL。 - 代码执行顺序错误:
client.run('token')是阻塞方法,放在事件定义前面会导致后面的on_message事件无法注册,必须把它移到所有事件定义的最后。 - 重复导入模块:代码里重复导入了
discord和re,清理后能让代码更整洁。
下面是修正后的完整代码,还添加了基础异常处理,避免Bot因请求失败、页面结构变化等情况崩溃:
import discord import re import requests import json from bs4 import BeautifulSoup intents = discord.Intents.all() client = discord.Client(intents=intents) @client.event async def on_ready(): print('We have logged in as {0.user}'.format(client)) @client.event async def on_message(message): if message.author == client.user: return if message.content.startswith('/channel '): # 剥离命令前缀,获取纯净的YouTube频道URL channelURL = message.content[len('/channel '):].strip() # 也可以用split方法实现:channelURL = message.content.split(' ', 1)[1].strip() # 简化URL有效性判断 if re.search(r'https?://.*youtu', channelURL, re.IGNORECASE): try: # 请求频道页面,携带同意Cookie绕过YouTube验证 response = requests.get(channelURL, cookies={'CONSENT': 'YES+1'}) response.raise_for_status() # 抛出HTTP请求错误 soup = BeautifulSoup(response.text, "html.parser") # 提取页面中的ytInitialData数据 data_match = re.search(r"var ytInitialData = ({.*?});", str(soup.prettify())) if not data_match: await message.channel.send("无法从页面提取频道信息") return json_data = json.loads(data_match.group(1)) # 安全获取频道数据,避免键不存在导致崩溃 header_renderer = json_data.get("header", {}).get("c4TabbedHeaderRenderer") if not header_renderer: await message.channel.send("无法识别该YouTube频道页面") return channel_id = header_renderer.get("channelId") channel_name = header_renderer.get("title") channel_logo = header_renderer.get("avatar", {}).get("thumbnails", [{}])[2].get("url", "无logo链接") channel_id_link = f"https://youtube.com/channel/{channel_id}" # 打印频道信息到控制台 print(f"Channel ID: {channel_id}") print(f"Channel Name: {channel_name}") print(f"Channel Logo: {channel_logo}") print(f"Channel ID Link: {channel_id_link}") # 下载频道logo图片 if channel_logo != "无logo链接": try: img_response = requests.get(channel_logo, allow_redirects=True) img_response.raise_for_status() with open('image.png', 'wb') as f: f.write(img_response.content) except Exception as e: print(f"下载logo失败: {e}") await message.channel.send(channel_id_link) except Exception as e: await message.channel.send(f"处理请求时出错: {str(e)}") print(f"错误详情: {e}") # 必须放在所有事件定义之后 client.run('你的Bot令牌')
额外注意事项
- 替换代码中的
你的Bot令牌为你实际的Discord Bot令牌。 - 确保已安装所有依赖:
pip install discord.py requests beautifulsoup4。 - YouTube页面结构可能会更新,若后续无法提取数据,需要调整正则表达式或数据提取路径。
内容的提问来源于stack exchange,提问作者flyinggoatman
相关产品推荐
相关产品推荐

