You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python3.6 tarfile模块从内存读取并下载URL中的tar文件解压?

解决从URL下载xz压缩Tar包并提取到本地的问题

我来帮你搞定这个问题!你遇到的两个错误其实都是有明确原因的,咱们一步步拆解解决:

先分析你遇到的错误

第一个错误:TypeError: expected str, bytes or os.PathLike object, not _io.BytesIO

你一开始直接把BytesIO对象传给了TarFile的第一个参数,而TarFile的第一个参数默认是文件路径字符串,要传入内存中的字节流,必须用fileobj关键字参数来指定——你后来的修改方向是对的,但还没解决核心问题。

第二个错误:tarfile.InvalidHeaderError: invalid header

这个问题的关键是:你下载的文件是tar.xz格式(xz压缩的tar包),而TarFile默认的mode='r'只会处理未压缩的tar文件,它无法自动识别xz压缩格式,所以才会报“无效头”的错误。

修正后的完整代码

我们只需要在创建TarFile时指定mode='r:xz',告诉它要处理xz压缩的tar包,同时正确传入fileobj参数即可:

#!/usr/bin/python3.6
# -*- coding: utf-8 -*-
from pathlib import Path
from io import BytesIO
from urllib.request import Request, urlopen
from urllib.error import URLError
from tarfile import TarFile

def get_url_response(url):
    req = Request(url)
    try:
        response = urlopen(req)
    except URLError as e:
        if hasattr(e, 'reason'):
            print('We failed to reach a server.')
            print('Reason: ', e.reason)
        elif hasattr(e, 'code'):
            print('The server couldn\'t fulfill the request.')
            print('Error code: ', e.code)
        return None  # 出错时返回None,避免后续调用read()报错
    else:
        # everything is fine
        return response

url = 'https://dl.opendesktop.org/api/files/download/id/1566630595/s/6cf6f74c4016e9b83f062dbb89092a0dfee862472300cebd0125c7a99463b78f4b912b3aaeb23adde33ea796ca9232decdde45bb65a8605bfd8abd05eaee37af/t/1567158438/c/6cf6f74c4016e9b83f062dbb89092a0dfee862472300cebd0125c7a99463b78f4b912b3aaeb23adde33ea796ca9232decdde45bb65a8605bfd8abd05eaee37af/lt/download/Blue-Maia.tar.xz'
dst = Path().cwd() / 'Tar'
response = get_url_response(url)

if response:  # 先判断响应是否有效
    # 指定mode='r:xz'处理xz压缩的tar包,同时传入内存字节流对象
    with TarFile.open(fileobj=BytesIO(response.read()), mode='r:xz') as tfile:
        tfile.extractall(path=dst)
        print(f"文件已成功提取到:{dst}")

补充说明

  • mode='r:xz'是核心:它告诉TarFile读取xz压缩的tar归档文件,同理如果是gz压缩的tar包,就用mode='r:gz'。
  • 我给get_url_response函数加了return None的逻辑,避免出错时response为None导致后续调用response.read()报错。
  • extractall会自动创建不存在的目标文件夹,所以不用额外手动创建dst路径。

内容的提问来源于stack exchange,提问作者Sun Bear

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:24:28