如何修复TypeError:只能将数组(不是“字节”)连接到数组?

如何修复TypeError:只能将数组(不是“字节”)连接到数组

最近我在学Python,从网上获取了一个作品,程序结果应该是从网上获取scratch文件。第一次执行时成功了,但是第二次就不行
部分代码:

self.zip_head = array("B", [80, 75, 3, 4, 10, 0, 0, 0])
self.data: bytes = resp.content
zip_data = self.zip_head + self.data[8:]

全部代码:

import requests
from os import mkdir
from copy import copy
from time import time
from urllib.request import quote, unquote
from os import listdir
from io import BytesIO
from array import array
from zipfile import ZipFile
from re import findall, sub
from base64 import b64decode
from Crypto.Cipher import AES
from DownloadKit import DownloadKit
from os.path import join as path_join, isfile, isdir
from json import loads as json_loads, dump as json_dump

output = r"D:\VideoTemp\ccw_output"


class Project:

    def __init__(self, project_id: str) -> None:
        self._id: str = project_id
        self.key: str = None
        self.data_url: str = None
        self.data: bytes = None
        self.json: dict = None
        self.json_text: str = None
        self.resource_list: list = None
        self.title: str = None
        self.zip_head = array("B", [80, 75, 3, 4, 10, 0, 0, 0])
        self.png_head = array("B", [55, 122, 188, 175, 9, 5, 2, 7])

    def download(self):
        print("开始下载")
        self.get_project_detail()
        self.get_project_data()
        self.get_project_json()
        self.get_project_resource_list()
        self.download_resources()
        self.save_json()
        self.save_detail()
        self.add_zip()

    def get_project_detail(self):
        url = "https://community-web.ccw.site/creation/detail"
        post_data = {"oid": self._id, "accessKey": ""}
        resp_json = requests.post(url, json=post_data).json()
        if resp_json["status"] == 200:
            self.title: str = resp_json["body"]["title"]
            self.data_url: str = resp_json["body"]["creationRelease"]["projectLink"]
            self.key: str = self.data_url.split("/")[-1].split(".")[0]
            self.detail: str = resp_json["body"]

    def get_project_data(self):
        resp = requests.get(self.data_url)
        self.data: bytes = resp.content

    def reverse_string(self, e):
        t = len(e) - 1
        n = str(t)[-1]
        r = e[t]
        return e[: int(n)] + r + e[int(n) + 1 : t]

    def get_project_json(self):
        file_head = array("B", self.data[:8])

        if file_head == self.png_head:  # 如果文件有PNG头, What???
            print("实行换头手术")
            print(self.zip_head)
            print("...")
            print(self.data[8:])
            print(type(self.zip_head),type(self.data[8:]))
            zip_data = self.zip_head + self.data[8:]
        elif file_head != self.zip_head:
            print("加密")
            self.data = self.decrypt(b64decode(self.data))
            zip_data = array("B", map(int, self.data.split(b",")))
        else:
            zip_data = copy(self.data)

        zip_archive = ZipFile(BytesIO(zip_data))  # 打开压缩包
        json_data = zip_archive.read("Project.json".lower())  # 提取出Project.json文件
        self.json_text = json_data.decode()
        if self.json_text.startswith("{"):
            self.json: dict = json_loads(self.json_text)  # 提取Json
        else:
            self.json_text = b64decode(self.reverse_string(json_data.decode())).decode()
            self.json_text = unquote(self.json_text)
            self.json: dict = json_loads(self.json_text)

        print("已获取作品Json")
        zip_archive.close()  # 关闭压缩包

    def get_project_resource_list(self):
        self.resource_list = findall("[0-9a-z]{32}\.[\w]{2,4}", self.json_text)
        print("作品资源数量:", len(self.resource_list))

    def download_resources(self):
        self.path_title = self.filter_basename(self.title)
        self.output = path_join(output, self.path_title)
        if not isdir(self.output):
            mkdir(self.output)
        kit = DownloadKit(roads=15)
        for resource_id in self.resource_list:
            resource_url = "https://m.ccw.site/user_projects_assets/" + resource_id
            kit.add(resource_url, self.output)
        kit.wait(show=True, timeout=10)

    def save_json(self):
        print("正在保存作品Json")
        with open(path_join(self.output, "project.json"), "w+", encoding="utf-8") as f:
            json_dump(self.json, f, ensure_ascii=False, indent=4)

    def save_detail(self):
        print("正在保存作品Detail")
        with open(path_join(self.output, "detail.json"), "w+", encoding="utf-8") as f:
            json_dump(self.detail, f, ensure_ascii=False, indent=4)

    def add_zip(self):
        zip = ZipFile(path_join(output, self.path_title + ".sb3"), "w")
        for name in listdir(self.output):
            fp = path_join(self.output, name)
            if isfile(fp):
                print("写入Zip:", name)
                with open(fp, "rb") as f:
                    zip.writestr(name, f.read())
        zip.close()

    def filter_basename(self, basename: str):
        return sub(r"|[\\/:*?\"<>|]+", "", basename.strip())

    def decrypt(self, data: bytes) -> str:
        key = b64decode("KzdnFCBRvq3" + self.key + "=")
        iv = key[:16]
        aes_obj = AES.new(key, AES.MODE_CBC, iv)
        return aes_obj.decrypt(data)


project = Project("63bd60e13b454c6f4cb340b0")
project.download()

第二次的时候一直提示“TypeError:can only append array (not "bytes") to array”
怎么才能把这个代码搞好?

阅读 373
avatarAI BotBETA

这个错误提示“TypeError:can only append array (not "bytes") to array”是因为你试图将bytes类型的数据添加到array类型的数据中,这在Python中是不被允许的。从错误提示来看,这个问题发生在zip_data = self.zip_head + self.data[8:]这行代码。

在这段代码中,self.zip_head是一个array类型的对象,而self.data[8:]是一个bytes类型的对象。Python不允许直接将这两种类型的对象相加。

要解决这个问题,你需要将bytes类型的数据转换为array类型的数据。你可以使用array.frombytes()方法来实现这个转换。这个方法可以接收一个bytes类型的对象,并将其转换为一个array类型的对象。

这是修改后的代码:

# ...

def get_project_json(self):
    file_head = array("B", self.data[:8])

    if file_head == self.png_head:  # 如果文件有PNG头, What???
        print("实行换头手术")
        print(self.zip_head)
        print("...")
        print(self.data[8:])
        print(type(self.zip_head),type(self.data[8:]))
        # 将bytes类型的数据转换为array类型的数据
        zip_data_bytes = self.data[8:]
        zip_data = self.zip_head + array("B", zip_data_bytes)
    elif file_head != self.zip_head:
        print("加密")
        self.data = self.decrypt(b64decode(self.data))
        # 将bytes类型的数据转换为array类型的数据
        zip_data = array("B", map(int, self.data.split(b",")))
    else:
        zip_data = copy(self.data)

    zip_archive = ZipFile(BytesIO(zip_data))  # 打开压缩包
    json_data = zip_archive.read("Project.json".lower())  # 提取出Project.json文件
    self.json_text = json_data.decode()
    if self.json_text.startswith("{"):
        self.json: dict = json_loads(self.json_text)  # 提取Json
    else:
        self.json_text = b64decode(self.reverse_string(json_data.decode())).decode()
        self.json_text = unquote(self.json_text)
        self.json: dict = json_loads(self.json_text)

    print("已获取作品Json")
    zip_archive.close()  # 关闭压缩包

# ...

在上述代码中,我添加了一个zip_data_bytes变量来存储self.data[8:]bytes数据,然后使用array("B", zip_data_bytes)将其转换为array类型的数据。这样,你就可以将self.zip_headzip_data_bytes转换为的array类型的数据相加了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题