Python Discord机器人可以';t使用线程,卡住错误:必需的位置参数:';ctx';

Python Discord机器人可以';t使用线程,卡住错误:必需的位置参数:';ctx';,python,discord,python-asyncio,discord.py,python-multithreading,Python,Discord,Python Asyncio,Discord.py,Python Multithreading,我试图让这个机器人有一个线程,这样它每24小时执行一次almanax协程,而不执行任何命令,但是当我尝试在另一个线程中这样调用它时,我得到一个错误(TypeError:almanax()缺少一个必需的位置参数:“ctx”),它需要ctx,我已经尝试过了,但我只是卡住了。我对这个完全陌生 import discord from discord.ext import commands import urllib.request import re import datetime from bs4 i

我试图让这个机器人有一个线程,这样它每24小时执行一次almanax协程,而不执行任何命令,但是当我尝试在另一个线程中这样调用它时,我得到一个错误(TypeError:almanax()缺少一个必需的位置参数:“ctx”),它需要ctx,我已经尝试过了,但我只是卡住了。我对这个完全陌生

import discord
from discord.ext import commands
import urllib.request
import re
import datetime
from bs4 import BeautifulSoup
import requests
import asyncio

bot = commands.Bot(command_prefix='-', description= "Este es un DuckBot")

sourceLinkAlmanax = 'http://www.krosmoz.com/es/almanax'
fechaexacta = '{0:%d-%m-%Y}'.format(datetime.datetime.now())

async def dailyAlmanax():
    while 1:
        await asyncio.sleep(5) #86400
        await almanax()

@bot.command()
async def almanax(ctx):
    print("Procesando almanax")

    source = requests.get(sourceLinkAlmanax).text

    soup = BeautifulSoup(source, 'lxml')

    mision = soup.find('div', class_='mid').p.text
    bonus = soup.find('div', class_='more').getText()
    ofrenda = soup.find('div', class_='more-infos-content').p.text
    bonus = bonus.replace(mision, "")
    bonus = bonus.replace(ofrenda, "")
    linkImagen = soup.find('div', {"class": "more-infos"}).img['src']

    fechaexacta = '{0:%d-%m-%Y}'.format(datetime.datetime.now())

    mensaje = discord.Embed(title = "`Duckmanax del " + fechaexacta + "`", url=sourceLinkAlmanax, color=0xe5be01)
    mensaje.add_field(name="Mision: ", value=f"{mision}", inline=False)
    mensaje.add_field(name="Bonus: ", value=f"{bonus.strip()}", inline=False)
    mensaje.add_field(name="Ofrenda: ", value=f"{ofrenda.strip()}", inline=False)
    mensaje.set_image(url=linkImagen)
    await ctx.send(embed = mensaje)

    print("Almanax enviado")

@bot.command()
async def salmanax(ctx, busqueda: str):
    print("Procesando busqueda de almanax")
    fecha = datetime.datetime.now()
    año = fecha.year
    smes = fecha.month
    sdia = fecha.day

    for mes in range (smes,13):

        if mes > smes:
            sdia = 1

        for dia in range (sdia,32):

            print("Procesando Año:", año, "Mes:", mes, "Dia:", dia, "Buscando:", busqueda)

            if mes < 10:
                mes2 = "0" + str(mes)
            else:
                mes2 = mes
            if dia < 10:
                dia2 = "0" + str (dia)
            else:
                dia2 = dia

            link = "http://www.krosmoz.com/es/almanax/" + str(año) + "-" + str(mes2) + "-" + str(dia2)

            try:
                data = urllib.request.urlopen(link).read().decode('utf-8')
            except Exception as error:
                pass

            for linea in data.split("/n"):
                try:
                    if re.findall(busqueda, linea, re.IGNORECASE):
                        await ctx.send("Encontre esta coincidencia de " + busqueda + " " + link)
                except Exception as error2:
                    pass
    print("Busqueda de almanax finalizada")

@bot.event
async def on_message(ctx):
    if ctx.channel.name == 'almanax':
        await bot.process_commands(ctx)

@bot.event
async def on_ready():
    print("Bot listo")
    await bot.change_presence(activity=discord.Streaming(name="-almanax",url="https://www.twitch.tv/kerdrai"))

bot.loop.create_task(dailyAlmanax())
bot.run(token)
导入不一致
从discord.ext导入命令
导入urllib.request
进口稀土
导入日期时间
从bs4导入BeautifulSoup
导入请求
导入异步
bot=commands.bot(命令前缀='-',description=“Este es un DuckBot”)
sourceLinkAlmanax=http://www.krosmoz.com/es/almanax'
fechaexacta='{0:%d-%m-%Y}'。格式(datetime.datetime.now())
异步def dailyAlmanax():
而1:
等待异步睡眠(5)#86400
等待almanax()
@bot.command()
异步def almanax(ctx):
印刷品(“Procesando almanax”)
source=requests.get(sourceLinkAlmanax).text
汤=BeautifulSoup(来源“lxml”)
mision=soup.find('div',class='mid').p.text
bonus=soup.find('div',class='more').getText()
ofrenda=soup.find('div',class='more-infos-content').p.text
奖金=奖金。更换(mision,“”)
奖金=奖金。替换(ofrenda,“”)
linkImagen=soup.find('div',{“class”:“more infos”}).img['src']
fechaexacta='{0:%d-%m-%Y}'。格式(datetime.datetime.now())
mensaje=discord.Embed(title=“`duckmanaxdel”+fechaexacta+””,url=sourceLinkAlmanax,color=0xe5be01)
mensaje.add_字段(name=“Mision:”,value=f“{Mision}”,inline=False)
mensaje.add_字段(name=“Bonus:”,value=f“{Bonus.strip()}”,inline=False)
add_字段(name=“Ofrenda:”,value=f“{Ofrenda.strip()}”,inline=False)
mensaje.set_图像(url=linkImagen)
等待ctx.send(嵌入=mensaje)
印刷品(“Almanax enviado”)
@bot.command()
异步def salmanax(ctx,总线:str):
印刷品(“阿尔马纳克斯省议会”)
fecha=datetime.datetime.now()
año=fecha.年
smes=fecha.month
sdia=fecha.day
对于范围内的mes(SME,13):
如果mes>SME:
sdia=1
对于范围内的直径(sdia,32):
印刷品(“Procesando Año:,Año,”Mes:,Mes,“Dia:,Dia”,“Buscando:,busqueda”)
如果mes<10:
mes2=“0”+str(mes)
其他:
mes2=mes
如果直径<10:
dia2=“0”+str(直径)
其他:
dia2=dia
链接=”http://www.krosmoz.com/es/almanax/“+str(año)+”-“+str(mes2)+”-“+str(dia2)
尝试:
data=urllib.request.urlopen(link.read().decode('utf-8'))
除异常作为错误外:
通过
对于数据中的linea.split(“/n”):
尝试:
如果关于findall(busqueda,linea,关于IGNORECASE):
等待ctx.send(“Encentre esta Concurrencia de”+busqueda+”+链接)
例外情况除外,如错误2:
通过
印刷品(“Busqueda de almanax finalizada”)
@机器人事件
异步def on_消息(ctx):
如果ctx.channel.name==“almanax”:
等待bot.process_命令(ctx)
@机器人事件
_ready()上的异步定义:
打印(“Bot listo”)
等待bot.change_状态(activity=discord.Streaming(name=“-almanax”,url=”)https://www.twitch.tv/kerdrai"))
bot.loop.create_任务(dailyAlmanax())
bot.run(令牌)

命令需要传递上下文对象,因此除非传递有效的上下文,否则
等待mycommand()
无效。有效的上下文是必需的,因为在
almanax()
命令中,它用于
await ctx.send(embed=mesaje)
,所以您不能只创建一个新的上下文对象并将其传入,然后期望它工作

您可以引用一个新的上下文对象,它非常适合使调用有效,但这太麻烦了,有更好的方法可以做到这一点。(如果您希望这样做,请对具有有效的almanax命令的消息使用
Bot.get_context()
方法,并将其作为参数传递到
wait almanax()
。这将导致每日消息从您拾取的消息所在的频道发送。)

source=requests.get(sourceLinkAlmanax).text

mensaje.set\u image(url=linkImagen)

可以外包到另一个函数中,您可以在
almanax()
中调用该函数,我将调用该函数
get\u almanax()
(您应该使该函数
异步,因为它依赖于等待响应),但是,您可以随意命名它。此函数返回在almanax()中发送的嵌入。然后,您可以将
dailyAlmanax()
almanax()
更改为如下内容:

async def dailyAlmanax():
    while 1:
        await asyncio.sleep(5) #86400
        mesaje = await get_almanax()
        channel = bot.get_channel(ID) #ID for the daily almanax channel
        await channel.send(embed = mesaje)
...

@bot.command()
async def almanax(ctx):
    print("Procesando almanax")

    mesaje = await get_almanax()
    await ctx.send(embed = mesaje)

get_almanax()
函数应该定义为我前面提到的行,以及您需要的任何输入(看起来没有必要,只是以防万一),它应该返回所需的嵌入。

命令需要传递上下文对象,所以
等待mycommand()
除非传递有效的上下文,否则无效。有效的上下文是必需的,因为在
almanax()
命令中,它用于
await ctx.send(embed=mesaje)
,所以您不能只创建一个新的上下文对象并将其传入,然后期望它工作

您可以引用一个新的上下文对象,它非常适合使调用有效,但这太麻烦了,有更好的方法可以做到这一点。(如果您希望这样做,请对具有有效的almanax命令的消息使用
Bot.get_context()
方法,并将其作为参数传递到
wait almanax()
。这将导致每日消息从您拾取的消息所在的频道发送。)

almanax命令的整个部分