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

使用urllib向网站JSON文件写入数据遇TypeError报错求助

无法通过urllib向远程JSON文件写入内容的问题修复

问题场景

我正在开发一款聊天机器人,通过urllib的urlopen函数加载网站上的bot.json文件,但无法向该JSON文件写入内容。

我的代码

import random
import json
from urllib.request import urlopen

url = "https://proj002webhostingserver.husseingaming1.repl.co/bot.json"
web = urlopen(url)


def random_string(question):
    random_list = [
        "Please try writing something more descriptive. Can You Please Respond With The Answer",
        "Oh! It appears you wrote something I don't understand yet, Can You Please Respond With The Answer",
        "Do you mind trying to rephrase that? Can You Please Respond With The Answer",
        "I'm terribly sorry, I didn't quite catch that. Can You Please Respond With The Answer",
        "I can't answer that yet, please try asking something else. Can You Please Respond With The Answer"
    ]

    list_count = len(random_list)
    random_item = random.randrange(list_count)
    web = urlopen(url)
    response_data = load_json(web)
    print(random_list[random_item])
    respinp = input("Type Your Response To That Question: ")
    reqwinp = list(input("Type Any Requierd Words Here(Leave empty if there are none)(use this format: [\"word1\", \"word 2\"] you can use more than 2 or less than 2): "))
    new(question=question, response= respinp, required_words= reqwinp)


def load_json(file):
    with urlopen(url) as bot_responses:
        print(f"Loaded \"{file}\" successfully!")
        return json.load(bot_responses)
    

def new(question: str, response: str, required_words: None and str):
    """_summary_

    Args:
        question (str): The question that you asked
        response (str): An answer to the question
        required_words (Noneandstr): any requierd words for this question(leave empty if there are no required words)
    """
    data = load_json(web)
    data.append({
    "response_type": "added",
    "user_input": [question],
    "bot_response": response,
    "required_words": [required_words]
                })
    with  urlopen(url, "w") as file:
        json.dumps(data, file)
random_string("hi")

运行错误信息

Exception has occurred: TypeError
POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.
  File "/Users/hussein/Desktop/Chatbot_proj_Callback001_version1/random_responses.py", line 49, in new
    with  urlopen(url, "w") as file:
          ^^^^^^^^^^^^^^^^^
  File "/Users/hussein/Desktop/Chatbot_proj_Callback001_version1/random_responses.py", line 25, in random_string
    new(question=question, response= respinp, required_words= reqwinp)
  File "/Users/hussein/Desktop/Chatbot_proj_Callback001_version1/random_responses.py", line 51, in <module>
    random_string("hi")
TypeError: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.

问题分析与修复方案

核心问题拆解

  1. urlopen用法错误:urlopen的第二个参数不是文件打开模式(如"w"),而是要发送的POST请求数据。传入"w"会被当成字符串类型的POST数据,不符合要求导致类型错误。
  2. 远程文件写入逻辑错误:不能像操作本地文件那样直接"写入"远程JSON,需要发送合法的HTTP请求(PUT/POST/PATCH,取决于服务器支持),并正确编码数据、设置请求头。
  3. 其他次要问题:
    • load_json函数的参数file未被使用,逻辑冗余
    • reqwinp用list(input(...))会把输入字符串拆成单个字符,应该用json.loads()解析列表格式输入
    • new函数的参数类型标注错误,required_words: None and str不符合语法规范

修复后的代码

import random
import json
from urllib.request import Request, urlopen
from typing import Optional, List

url = "https://proj002webhostingserver.husseingaming1.repl.co/bot.json"

def random_string(question):
    random_list = [
        "请尝试描述得更详细一些,请给出对应的答案",
        "哦!看起来你写了一些我还不理解的内容,请给出对应的答案",
        "你介意重新表述一下吗?请给出对应的答案",
        "非常抱歉,我没太听清,请给出对应的答案",
        "我还无法回答这个问题,请尝试问点别的。请给出对应的答案"
    ]

    random_item = random.randrange(len(random_list))
    print(random_list[random_item])
    respinp = input("输入该问题的回复: ")
    reqwinp_input = input("输入所需关键词(无则留空,格式:[\"word1\", \"word2\"],可多可少): ")
    # 解析用户输入的列表格式,无输入则设为空列表
    reqwinp = json.loads(reqwinp_input) if reqwinp_input.strip() else []
    new(question=question, response=respinp, required_words=reqwinp)

def load_json():
    with urlopen(url) as bot_responses:
        print("加载bot.json成功!")
        return json.load(bot_responses)

def new(question: str, response: str, required_words: Optional[List[str]]):
    data = load_json()
    data.append({
        "response_type": "added",
        "user_input": [question],
        "bot_response": response,
        "required_words": required_words
    })
    # 将JSON数据编码为字节格式
    json_data = json.dumps(data).encode('utf-8')
    # 创建PUT请求(若服务器支持POST则改为POST)
    req = Request(url, data=json_data, method='PUT')
    # 设置请求头,告知服务器数据类型为JSON
    req.add_header('Content-Type', 'application/json')
    # 发送请求并处理响应
    with urlopen(req) as response:
        print("数据写入成功!")
        print(response.read().decode('utf-8'))

random_string("hi")

额外注意事项

  • 确认服务器支持修改bot.json的HTTP方法(PUT/POST/PATCH),若只允许特定方法需对应调整代码中的method参数
  • 若服务器需要身份验证,需在请求头中添加对应的认证信息
  • 处理用户输入时建议添加异常捕获,避免因输入格式错误导致程序崩溃

内容的提问来源于stack exchange,提问作者Nothing Around Us

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:22:05