【问题标题】:Download file with resume capability using aiohttp and python使用 aiohttp 和 python 下载具有恢复功能的文件
【发布时间】:2019-10-20 01:49:28
【问题描述】:

我想使用aiohttp 流式传输和下载文件。 Chrome可以支持下载链接的恢复能力 但下载管理器无法下载具有恢复功能的文件。

在下面的代码中,我使用 aiohttp 框架来流式传输和下载文件, 我还设置了标头参数 ('Accept-Ranges') 以支持恢复功能。

from telethon import TelegramClient, events
client = TelegramClient(name, api_id,api_hash)

@routes.get('/{userid}/{msgid}')
async def handle(request):
    ...
    response = web.StreamResponse(
        status=200,
        reason='OK',
        headers={
            'Content-Type': content_type,
            'Content-Length':str(file_size),
            'Accept-Ranges': 'bytes',
            'Connection': 'keep-alive',
        }
    )
    await response.prepare(request)
    async for chunk in client.iter_download(msg.media, chunk_size=512):
        await response.write(chunk)
    return response

app = web.Application()
app.add_routes(routes)
web.run_app(app,host='0.0.0.0')

当在浏览器中点击下载链接时,文件流式传输良好。 Chrome 很好地支持恢复功能, 我希望下载管理器能够很好地支持恢复功能,但是在暂停并再次开始下载后,下载管理器无法继续下载并要求用户重新开始下载。 消息IDM 给出:“尝试恢复下载时,互联网下载管理器从服务器得到响应,它不支持恢复下载......”

【问题讨论】:

  • 似乎是IDM 的问题,aiohttptelethon 部分对我来说看起来是正确的。你甚至声称 Chrome 在这方面没有问题。
  • 是的。我对 Chrome 没有任何问题。我需要为 http 标头编写额外的代码还是在 teleton 中完成?
  • 另外,你应该使用iter_download 中的offset= 参数来“从字节偏移量恢复”。但即便如此,它也无法解释 IDM 失败的原因。

标签: python-3.x stream aiohttp download-manager telethon


【解决方案1】:

基于此streamer implementation,您似乎缺少Content-Rangestatus=206 以指示Partial Content

可能类似于以下内容可能会起作用。请注意,它没有进行足够的验证(即标头中的 Range 可能无效)。

import re

...

async def handle(request):
    offset = request.headers.get('Range', 0)
    if not isinstance(offset, int):
        offset = int(re.match(r'bytes=(\d+)', offset).group(1))

    size = message.file.size
    response = web.StreamResponse(
        headers={
            'Content-Type': 'application/octet-stream',
            'Accept-Ranges': 'bytes',
            'Content-Range': f'bytes {offset}-{size}/{size}'
        },
        status=206 if offset else 200,
    )
    await response.prepare(request)

    async for part in client.iter_download(message.media, offset=offset):
        await response.write(part)

    return response

【讨论】:

  • 当我设置 ‍‍‍‍status=206 if offset else 200 时,它很容易进入 Chrome pausestart 但在 IDM 按钮内 startpause 未激活。当我在 Chrome 中设置status=206 时失败,但它在IDM startpause 上激活,但是当我点击pausestart 下载时,出现以下错误:telethon.errors.rpcerrorlist.LimitInvalidError: An invalid limit was provided. See https://core.telegram.org/api/files#downloading-files (caused by GetFileRequest)
  • 我在我的服务器上测试了webgram,但IDM 也有问题。IDM 内部的按钮启动和暂停未激活,但在 chrome 内部一切都很好
  • LimitInvalidError 应该由iter_download 正确处理,所以这可能是库中的错误。
  • 我发现aiohttpIDM有问题,与telethon包无关
猜你喜欢
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-27
  • 2019-11-20
  • 2019-08-08
相关资源
最近更新 更多