Discord.py не может запуститься при парсинге
import requests
from bs4 import BeautifulSoup
import discord
import random
from discord.ext import commands, tasks
import asyncio
import time
URL = 'https://stopgame.ru/news'
HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0', 'accept':'*/*'}
link = 'https://stopgame.ru'
Token = ''
api_key = "I need your token"
base_url = "http://api.openweathermap.org/data/2.5/weather?"
PREFIX = 'lu.'
intents = discord.Intents.all()
client = commands.Bot(command_prefix=PREFIX, intents=intents)
client.remove_command('help')
def get_html(url, params=None):
while True:
r = requests.get(url, headers = HEADERS, params = params )
return r
time.sleep(10)
v = []
newsw = []
bb = []
def get_content(html):
soup = BeautifulSoup(html, 'html.parser')
for x in soup.select('.article-summary .caption'):
newsw.append(x.get_text(strip=True))
articles = soup.find_all('div', class_='caption caption-bold')
for a in articles:
bb.append(link+a.find('a')['href'])
yu = soup.find_all('span', class_ = 'info-item timestamp')
for c in yu:
v.append(c.get_text())
return v, newsw, bb
def parse():
while True:
html = get_html(URL)
print (html)
get_content (html.text)
time.sleep(10)
parse()
@client.command()
async def stopgame(ctx):
cvh = discord.Embed(title = 'StopGame', color = 0xFF0000)
cvh.add_field(name = 'Заголовок:', value = f'1. {newsw[0]} \n 2. {newsw[1]} \n 3. {newsw[2]} \n 4. {newsw[3]} \n 5. {newsw[4]}')
cvh.add_field(name = 'Ссылка:', value = f'1.{bb[0]} \n 2.{bb[1]} \n 3.{bb[2]} \n 4.{bb[3]} \n 5.{bb[4]}')
cvh.add_field(name = 'Дата:', value = f'1. {v[0]} \n 2. {v[1]} \n 3. {v[2]} \n 4. {v[3]} \n 5. {v[4]}')
cvh.set_footer(text=f'Нет, код не списан у Хавуди Хо (Я серъезно)', icon_url = 'https://cdn.discordapp.com/attachments/776796284152971274/793456242201853982/unnamed.jpg')
await ctx.send(embed = cvh)
client.run(Token)
Discord.py не может запуститься, когда выполняются следующие строчки кода:
def parse():
while True:
html = get_html(URL)
print (html)
get_content (html.text)
time.sleep(10)
parse()
Без while код выполняется, но я хочу сделать так, чтобы он парсил новую информацию каждые 10 секунд.
Результат c while:

Ответы (2 шт):
Я думаю циклы вообще не нужны, есть же сущность бота, а у нее события, вот ближайший код который я делал для пересылки сообщений в телеграм (JS для питона долно быть точно такое же решение, но с питоновским синтаксисом):
discordClient.on('message', msg => {
if (DISCORD_CONFIG.channels.indexOf(msg.channel.name) >= 0) {
functions.resendMessage(msg);
}
});
Вот для питона:
@client.event
async def on_message(message):
await message.channel.send('C Новым Годом! ??')
How to Make a Discord Bot in Python
Что касается discord.ext (вот пример из документации):
async def on_ready(): pass
async def my_message(message): pass
bot.add_listener(on_ready)
bot.add_listener(my_message, 'on_message')
В общем и целом боты пишутся примерно одинаково на любом языке.
discord.py - асинхронная библиотека. requests - синхронная.
requests и time.sleep блокируют выполнение основного цикла.
В основном, всё что выполняется более 100ms - считается блокирующим.
- Используйте асинхронную библиотеку для веб-запросов, например
aiohttp. - Для "сна" используйте
asyncio.sleepвместоtime.sleep. - Используйте
asyncio tasksдля выполнения функции "в фоне".discord.pyимеет встроенное расширения для упрощённого управления задачами в контексте дискорд-ботов: https://discordpy.readthedocs.io/en/stable/ext/tasks/index.html
В итоге ваша блокирующая функция должна выглядеть примерно следующим образом:
import aiohttp
from discord.ext import tasks
...
async def get_html(url, params=None):
# raise_for_status - поднимаем исключение если статус ответа >=400
async with aiohttp.ClientSession(raise_for_status=True) as session:
async with session.get(url, headers=HEADERS, params=params) as response:
return response
@tasks.loop(seconds=10)
async def parse():
try:
html = await get_html(URL)
except aiohttp.ClientError as e:
print(e)
else:
get_content(html.text)
parse.start()
