json_utils.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import orjson
  2. from loguru import logger
  3. import ast
  4. def parse_general_json(response_text, key=None):
  5. """
  6. 通用的 JSON 解析方法,兼容单引号和双引号的 JSON 字符串。
  7. 优先尝试标准 JSON 解析,失败后尝试处理单引号情况。
  8. :param response_text: 待解析的 JSON 字符串
  9. :param key: 若指定,则从解析结果中提取该键对应的值,默认为 None
  10. :return: 解析结果,如果指定了 key 则返回对应的值,解析失败返回 None
  11. """
  12. # 处理字符串未闭合的情况,尝试修正
  13. response_text = fix_unclosed_string(response_text)
  14. try:
  15. # 优先尝试使用 orjson.loads 解析标准 JSON 格式
  16. data = orjson.loads(response_text.strip())
  17. except orjson.JSONDecodeError:
  18. try:
  19. # 若 orjson.loads 解析失败,尝试使用 ast.literal_eval 处理单引号情况
  20. data = ast.literal_eval(response_text.strip())
  21. except (SyntaxError, ValueError) as e:
  22. # 记录解析错误信息
  23. logger.error(f"JSON 解析错误, 响应内容: {response_text}, 错误信息: {e}")
  24. return None
  25. if key is not None:
  26. try:
  27. return data[key]
  28. except KeyError:
  29. logger.error(f"键 {key} 不存在于解析结果中,响应内容: {response_text}")
  30. return None
  31. return data
  32. def fix_unclosed_string(text):
  33. """
  34. 尝试修复未闭合的字符串
  35. :param text: 输入的文本
  36. :return: 修复后的文本
  37. """
  38. try:
  39. # 查找未闭合的字符串
  40. open_quotes = []
  41. for _, char in enumerate(text):
  42. if char in ['"', "'"]:
  43. if open_quotes and open_quotes[-1] == char:
  44. open_quotes.pop()
  45. else:
  46. open_quotes.append(char)
  47. if open_quotes:
  48. # 如果存在未闭合的字符串,尝试在末尾添加闭合引号
  49. closing_quote = open_quotes[-1]
  50. text = text.rstrip() + closing_quote
  51. return text
  52. except:
  53. return text
  54. if __name__ == '__main__':
  55. # 测试正常解析情况 - 标准 JSON(双引号)
  56. standard_json = '{"text": "这是标准 JSON 测试内容"}'
  57. result_standard = parse_general_json(standard_json, key='text')
  58. print("标准 JSON 解析结果:", result_standard)
  59. # 测试正常解析情况 - 非标准 JSON(单引号)
  60. non_standard_json = "{'text': '这是非标准 JSON 测试内容'}"
  61. result_non_standard = parse_general_json(non_standard_json, key='text')
  62. print("非标准 JSON 解析结果:", result_non_standard)