【问题标题】:How to download a file that was sent to my bot?如何下载发送到我的机器人的文件?
【发布时间】:2021-12-30 11:19:10
【问题描述】:
@dp.message_handler(content_types=types.ContentType.DOCUMENT)
async def scan_message(file: types.File):
    print("downloading document")
    file_path = file.file_path
    destination = r"C:\users\aleks\PycharmProjects\pythonProject\file.pdf"
    destination_file = bot.download_file(file_path, destination)
    print("success")

我希望能够下载用户发送给我的机器人的文件(在本例中为 pdf)。但问题是机器人甚至不识别文件(当我发送文件时,它甚至不打印“下载文档”)

【问题讨论】:

  • @Abdul Muiz,对不起,但这没有帮助。当我运行这段代码时,我被告知我不能使用 await 关键字声明变量

标签: python bots telegram aiogram


【解决方案1】:

您没有指定 aiogram 的版本。我猜是 2.x。

所有注册的异步函数,作为消息处理程序必须以第一个位置参数接收消息。如果你喜欢类型提示,你必须将你的函数指定为

async def scan_message(message: types.Message):

要下载您的文档,您只需要:

destination_file = await message.document.download(destination)

所以正确的下载文件处理程序是:

async def scan_message(message: types.Message):
    print("downloading document")
    destination = r"C:\users\aleks\PycharmProjects\pythonProject\file.pdf"
    destination_file = await message.document.download(destination)
    print("success")

【讨论】:

    【解决方案2】:

    TL;DR

    我希望您使用的是 aiogram v2.x。

    确保这是types.ContentType.DOCUMENT 没有过滤器的唯一处理程序和你的机器人can get needed updates,然后:

    @dp.message_handler(content_types=types.ContentType.DOCUMENT)
    async def scan_message(message: types.Message):
        print("downloading document")
        destination = r"C:\users\aleks\PycharmProjects\pythonProject\file.pdf"
        await message.document.download(destination)
        print("success")
    

    详细

    下面描述的所有内容都适用于 stable aiogram v2.x。

    1. aiogram.Dispatcher 类解析原始电报 Updatesends 它解析并解包到相应的处理程序,例如对于包含 message 的更新,dp.message_handler 将收到 aiogram.types.Message,对于包含 callback_query 的更新,dp.callback_query_handler 将收到 aiogram.types.CallbackQuery 等等。在您的情况下,您期待aiogram.types.File,这是错误的。然后调度器检查过滤器并按注册顺序调用相应的处理程序,如果调用了任何处理程序,则停止调度。

      考虑以下示例:

      # Some code omitted in favor of brievity
      @dp.message_handler()
      async def handle1(msg: types.Message):
          print("handled 1")
      
      @dp.message_handler()
      async def handle2(msg: types.Message):
          print("handled 2")
      

      您发送任何文本消息,然后查看机器人的控制台。只会打印“handled 1”,因为它是第一个匹配的处理程序,并且只调用了一个处理程序。

    2. 聊天机器人在群聊中具有所谓的“隐私模式”,因此并非每条消息都会发送给群组中的机器人。在私人(直接)消息中情况并非如此,因此最好私下测试您的机器人。您可以在官方 Bot API 文档中阅读有关隐私模式的更多信息:https://core.telegram.org/bots#privacy-mode

    3. 使用包含在每个类中的快捷方式会更好,更易读,例如您可以将.reply().answer() 转换为aiogram.types.Message,这是aiogram.Bot.send_message() 的快捷方式。与下载文件相同,您可以在aiogram.types.Documentaiogram.types.PhotoSize 等上使用.download()。您可以通过查找实现 aiogram.types.mixins.Downloadable 的类来找到更多可下载的类型。

    4. 所有.download() 方法都返回保存文件的目的地。如果您将自己的可选目标作为第一个参数传递给该方法,那么将其取回您已经知道的将毫无用处。

    因此,在这些修改之后,您将获得 TL;DR 部分中的代码。

    【讨论】:

      猜你喜欢
      • 2015-09-14
      • 2011-03-08
      • 1970-01-01
      • 1970-01-01
      • 2019-06-09
      • 2021-05-08
      • 2020-04-02
      • 2019-06-02
      • 2017-09-01
      相关资源
      最近更新 更多