需要一个类似字节的对象,而不是 'str' JSON 文件以 STR 形式打开

Posted

技术标签:

【中文标题】需要一个类似字节的对象,而不是 \'str\' JSON 文件以 STR 形式打开【英文标题】:a bytes-like object is required, not 'str' JSON File opened as STR需要一个类似字节的对象,而不是 'str' JSON 文件以 STR 形式打开 【发布时间】:2016-02-24 22:01:05 【问题描述】:

我只学习了 Python 的基础知识,请原谅我,但我无法从其他帖子中确定修复方法。我用 'r' 打开我的 JSON 文件,我想我正在用 r 给它们写信,但它不喜欢那样。将其更改为 'r' 没有帮助:(

对于以下部分:

if isinstance(to_write, list):
    self.log_file.write(''.join(to_write) + "<r/>")
else:
    self.log_file.write(str(to_write) + "<r/>")
    self.log_file.flush()

我得到的错误是:a bytes-like object is required, not 'str'

import math
import time
from random import randint
import json

from instagram.client import InstagramAPI

class Bot:
    def __init__(self, config_file, tags_file):
        # Loading the configuration file, it has the access_token, user_id and others configs
        self.config = json.load(config_file)

        # Loading the tags file, it will be keep up to date while the script is running
        self.tags = json.load(tags_file)

        # Log file to output to html the debugging info about the script
        self.filename = self.config["path"] + self.config["prefix_name"] + time.strftime("%d%m%Y") + ".html"
        self.log_file = open(self.filename, "wb")

        # Initializing the Instagram API with our access token
        self.api = InstagramAPI(access_token=self.config["access_token"], client_secret=self.config['client_secret'])

        # Likes per tag rate
        self.likes_per_tag = math.trunc(min(self.config["follows_per_hour"],
                                            self.config["likes_per_hour"]) / len(self.tags["tags"]))

    def save_tags(self):
        j = json.dumps(self.tags, indent=4)
        f = open('tags.json', 'w')
        print >> f, j
        f.close()

    def insta_write(self, to_write):
        if self.filename != self.config["path"] + self.config["prefix_name"] + time.strftime("%d%m%Y") + ".html":
            self.log_file.close()
            self.filename = self.config["path"] + self.config["prefix_name"] + time.strftime("%d%m%Y") + ".html"
            self.log_file = open(self.filename, "wb")

        if isinstance(to_write, list):
            self.log_file.write(''.join(to_write) + "<r/>")
        else:
            self.log_file.write(str(to_write) + "<r/>")
            self.log_file.flush()

    def going_sleep(self, timer):
        sleep = randint(timer, 2 * timer)
        self.insta_write("SLEEP " + str(sleep))
        time.sleep(sleep)

    def like_and_follow(self, media, likes_for_this_tag):
        try:
            var = self.api.user_relationship(user_id=media.user.id)

            if self.config["my_user_id"] != media.user.id:
                self.insta_write("--------------")
                self.insta_write(var)

                if var.outgoing_status == 'none':
                    self.insta_write("LIKE RESULT:")
                    self.insta_write(self.api.like_media(media_id=media.id))

                    self.insta_write("FOLLOW RESULT:")
                    self.insta_write(self.api.follow_user(user_id=media.user.id))

                    likes_for_this_tag -= 1

                    self.going_sleep(self.config["sleep_timer"])
                else:
                    self.going_sleep(self.config["sleep_timer"] / 2)

        except Exception as e:
            self.insta_write(str(e))
            self.insta_write("GOING SLEEP 30 min")
            time.sleep(1800)
            self.like_and_follow(media, likes_for_this_tag)

        return likes_for_this_tag

    def run(self):
        while True:
            for tag in self.tags["tags"].keys():
                tag = str(tag)

                self.insta_write("--------------------")
                self.insta_write("TAG: " + tag)
                self.insta_write("--------------------")

                self.insta_write("--------------------")
                self.insta_write("DICTIONARY STATUS:")

                for keys, values in self.tags["tags"].items():
                    self.insta_write(keys)
                    if values is not None:
                        self.insta_write(values)

                likes_for_this_tag = self.likes_per_tag

                while likes_for_this_tag > 0 and self.tags["tags"][tag] != 0:
                    if self.tags["tags"][tag] is None:
                        media_tag, self.tags["tags"][tag] = self.api.tag_recent_media(tag_name=tag,
                                                                                      count=likes_for_this_tag)
                    else:
                        media_tag, self.tags["tags"][tag] = self.api.tag_recent_media(tag_name=tag,
                                                                                      count=likes_for_this_tag,
                                                                                      max_tag_id=self.tags["tags"][tag])

                    self.insta_write("API CALL DONE")

                    if len(media_tag) == 0 or self.tags["tags"][tag] is None:
                        self.tags["tags"][tag] = 0
                        likes_for_this_tag = 0
                    else:
                        self.insta_write(self.tags["tags"][tag])
                        self.tags["tags"][tag] = self.tags["tags"][tag].split("&")[-1:][0].split("=")[1]

                    self.save_tags()

                    for m in media_tag:
                        likes_for_this_tag = self.like_and_follow(m, likes_for_this_tag)

                if reduce(lambda r, h: r and h[1] == 0, self.tags["tags"].items(), True):
                    self.insta_write("END")
                    exit(1)  

if __name__ == '__main__':
    bot = Bot(open("config_bot.json", "r"), open("tags.json", "r"))
    bot.run()

【问题讨论】:

【参考方案1】:

您将文件作为二进制文件打开:

self.log_file = open(self.filename, "wb")

但正在向其写入str Unicode 字符串。以文本模式(使用编码集)打开文件或分别对每个字符串进行编码。

以文本模式打开文件最简单:

self.log_file = open(self.filename, "w", encoding="utf8")

【讨论】:

我经常看到encoding="utf-8"(带连字符),是必需的吗? @Cai:不,破折号是可选的。您也可以使用下划线。见documentation; U8UTF 也是有效的别名。 我在tempfile.NamedTemporaryFile 遇到了这个问题,它默认使用mode='w+b' 打开文件(这是二进制模式)。

以上是关于需要一个类似字节的对象,而不是 'str' JSON 文件以 STR 形式打开的主要内容,如果未能解决你的问题,请参考以下文章

string - Python 3.5 需要写一个类似字节的对象,而不是'str'

TypeError:需要一个类似字节的对象,而不是'str'-python 2到3 [重复]

“TypeError:在 OAuth 2.0 回调请求期间需要一个类似字节的对象,而不是 'str'”

laravel 8.x - 帆 - 对于 mysql,需要一个类似字节的对象,而不是 'str'

诱变剂:TypeError:需要一个类似字节的对象,而不是“str”

TypeError:需要一个类似字节的对象,而不是“str”套接字编程