如何在 Python 中检查字符串是否为有效的 JSON?

发布于 2024-10-29 02:18:45 字数 110 浏览 3 评论 0 原文

在Python中,有没有办法在尝试解析字符串之前检查它是否是有效的JSON?

例如,使用 Facebook Graph API 之类的东西,有时它会返回 JSON,有时它可能会返回图像文件。

In Python, is there a way to check if a string is valid JSON before trying to parse it?

For example working with things like the Facebook Graph API, sometimes it returns JSON, sometimes it could return an image file.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

此刻的回忆 2024-11-05 02:18:45

您可以尝试执行json.loads(),如果您传递的字符串无法解码为JSON,它将抛出ValueError

一般来说,针对这种情况的“Pythonic”哲学被称为EAFP,因为请求宽恕比请求许可更容易

You can try to do json.loads(), which will throw a ValueError if the string you pass can't be decoded as JSON.

In general, the "Pythonic" philosophy for this kind of situation is called EAFP, for Easier to Ask for Forgiveness than Permission.

吃素的狼 2024-11-05 02:18:45

如果字符串是有效的 json,示例 Python 脚本将返回一个布尔值:

import json

def is_json(myjson):
  try:
    json.loads(myjson)
  except ValueError as e:
    return False
  return True

其中打印:

print is_json("{}")                          #prints True
print is_json("{asdf}")                      #prints False
print is_json('{ "age":100}')                #prints True
print is_json("{'age':100 }")                #prints False
print is_json("{\"age\":100 }")              #prints True
print is_json('{"age":100 }')                #prints True
print is_json('{"foo":[5,6.8],"foo":"bar"}') #prints True

将 JSON 字符串转换为 Python 字典:

import json
mydict = json.loads('{"foo":"bar"}')
print(mydict['foo'])    #prints bar

mylist = json.loads("[5,6,7]")
print(mylist)
[5, 6, 7]

将 python 对象转换为 JSON 字符串:

foo = {}
foo['gummy'] = 'bear'
print(json.dumps(foo))           #prints {"gummy": "bear"}

如果需要访问低级解析,不要自己动手,使用现有的库: http://www.json.org /

关于 python JSON 模块的精彩教程:https://pymotw.com/2/json/

是字符串 JSON 并显示语法错误和错误消息:

sudo cpan JSON::XS
echo '{"foo":[5,6.8],"foo":"bar" bar}' > myjson.json
json_xs -t none < myjson.json

打印:

, or } expected while parsing object/hash, at character offset 28 (before "bar}
at /usr/local/bin/json_xs line 183, <STDIN> line 1.

json_xs 能够进行语法检查、解析、压缩、编码、解码等:

https://metacpan.org/pod/json_xs

Example Python script returns a boolean if a string is valid json:

import json

def is_json(myjson):
  try:
    json.loads(myjson)
  except ValueError as e:
    return False
  return True

Which prints:

print is_json("{}")                          #prints True
print is_json("{asdf}")                      #prints False
print is_json('{ "age":100}')                #prints True
print is_json("{'age':100 }")                #prints False
print is_json("{\"age\":100 }")              #prints True
print is_json('{"age":100 }')                #prints True
print is_json('{"foo":[5,6.8],"foo":"bar"}') #prints True

Convert a JSON string to a Python dictionary:

import json
mydict = json.loads('{"foo":"bar"}')
print(mydict['foo'])    #prints bar

mylist = json.loads("[5,6,7]")
print(mylist)
[5, 6, 7]

Convert a python object to JSON string:

foo = {}
foo['gummy'] = 'bear'
print(json.dumps(foo))           #prints {"gummy": "bear"}

If you want access to low-level parsing, don't roll your own, use an existing library: http://www.json.org/

Great tutorial on python JSON module: https://pymotw.com/2/json/

Is String JSON and show syntax errors and error messages:

sudo cpan JSON::XS
echo '{"foo":[5,6.8],"foo":"bar" bar}' > myjson.json
json_xs -t none < myjson.json

Prints:

, or } expected while parsing object/hash, at character offset 28 (before "bar}
at /usr/local/bin/json_xs line 183, <STDIN> line 1.

json_xs is capable of syntax checking, parsing, prittifying, encoding, decoding and more:

https://metacpan.org/pod/json_xs

燕归巢 2024-11-05 02:18:45

我想说的是,解析它是你真正能够完全分辨的唯一方法。如果格式不正确,Python 的 json.loads() 函数(几乎肯定)会引发异常。但是,您示例的目的可能只是检查前几个非空白字符...

我不熟悉 facebook 发回的 JSON,但来自 Web 应用程序的大多数 JSON 字符串将以空心方块开头[ 或大括号 {。据我所知,没有任何图像格式以这些字符开头。

相反,如果您知道可能显示哪些图像格式,则可以检查字符串的开头以获取其签名来识别图像,如果不是图像,则假设您有 JSON。

识别图形而不是文本字符串的另一个简单技巧是,如果您正在寻找图形,则只需测试字符串的前几十个字符中的非 ASCII 字符(假设 JSON 是 ASCII )。

I would say parsing it is the only way you can really entirely tell. Exception will be raised by python's json.loads() function (almost certainly) if not the correct format. However, the the purposes of your example you can probably just check the first couple of non-whitespace characters...

I'm not familiar with the JSON that facebook sends back, but most JSON strings from web apps will start with a open square [ or curly { bracket. No images formats I know of start with those characters.

Conversely if you know what image formats might show up, you can check the start of the string for their signatures to identify images, and assume you have JSON if it's not an image.

Another simple hack to identify a graphic, rather than a text string, in the case you're looking for a graphic, is just to test for non-ASCII characters in the first couple of dozen characters of the string (assuming the JSON is ASCII).

百思不得你姐 2024-11-05 02:18:45

我还使用 json.loads() 来检查字符串是否是有效的 JSON,但我还需要检查它是否是复杂的数据结构。例如,我不想将简单的字符串或整数保存到数据库......
这些也是有效的 JSON,但有时也必须进行过滤:

  • "\"valid json\""
  • "1"
  • "3.14"

My解决方案在这里:

def is_json(string: str, is_complex: bool = False) -> bool:
    """
    Return True if the given string is in valid JSON format, else return False.

    Example usage
    -------------
    >>> is_json("1")       # True because this is a valid JSON string
    True

    >>> is_json("1", True) # return False because this is a simple data structure (int)
    False

    :param string:
    :param is_complex: bool; If true also checked for complex data structure
    :return: bool
    """
    try:
        valid_json = json.loads(string)
        if is_complex and type(valid_json) in [int, str, float, bool]:
            return False
    except ValueError:
        return False
    return True

I also used json.loads() to check if a string is a valid JSON, however I also needed to check if it is complex data structure or not. I did not want to save to the db a simple string or an integer for example...
These are also valid JSON, but sometimes must be filter as well:

  • "\"valid json\""
  • "1"
  • "3.14"

My solution is here:

def is_json(string: str, is_complex: bool = False) -> bool:
    """
    Return True if the given string is in valid JSON format, else return False.

    Example usage
    -------------
    >>> is_json("1")       # True because this is a valid JSON string
    True

    >>> is_json("1", True) # return False because this is a simple data structure (int)
    False

    :param string:
    :param is_complex: bool; If true also checked for complex data structure
    :return: bool
    """
    try:
        valid_json = json.loads(string)
        if is_complex and type(valid_json) in [int, str, float, bool]:
            return False
    except ValueError:
        return False
    return True
西瓜 2024-11-05 02:18:45

一种检查有效 JSON 的有效且可靠的方法。如果“get”访问器未抛出 AttributeError,则 JSON 有效。

import json

valid_json =  {'type': 'doc', 'version': 1, 'content': [{'type': 'paragraph', 'content': [{'text': 'Request for widget', 'type': 'text'}]}]}
invalid_json = 'opo'

def check_json(p, attr):
    doc = json.loads(json.dumps(p))
    try:
        doc.get(attr) # we don't care if the value exists. Only that 'get()' is accessible
        return True
    except AttributeError:
        return False
   

使用时,我们调用该函数并查找密钥。

# Valid JSON
print(check_json(valid_json, 'type'))

返回“真”

# Invalid JSON / Key not found
print(check_json(invalid_json, 'type'))

返回“假”

An effective, and reliable way to check for valid JSON. If the 'get' accessor does't throw an AttributeError then the JSON is valid.

import json

valid_json =  {'type': 'doc', 'version': 1, 'content': [{'type': 'paragraph', 'content': [{'text': 'Request for widget', 'type': 'text'}]}]}
invalid_json = 'opo'

def check_json(p, attr):
    doc = json.loads(json.dumps(p))
    try:
        doc.get(attr) # we don't care if the value exists. Only that 'get()' is accessible
        return True
    except AttributeError:
        return False
   

To use, we call the function and look for a key.

# Valid JSON
print(check_json(valid_json, 'type'))

Returns 'True'

# Invalid JSON / Key not found
print(check_json(invalid_json, 'type'))

Returns 'False'

温柔戏命师 2024-11-05 02:18:45

我想出了一个通用的、有趣的解决方案来解决这个问题:

class SafeInvocator(object):
    def __init__(self, module):
        self._module = module

    def _safe(self, func):
        def inner(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except:
                return None

        return inner

    def __getattr__(self, item):
        obj = getattr(self.module, item)
        return self._safe(obj) if hasattr(obj, '__call__') else obj

你可以像这样使用它:

safe_json = SafeInvocator(json)
text = "{'foo':'bar'}"
item = safe_json.loads(text)
if item:
    # do something

I came up with an generic, interesting solution to this problem:

class SafeInvocator(object):
    def __init__(self, module):
        self._module = module

    def _safe(self, func):
        def inner(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except:
                return None

        return inner

    def __getattr__(self, item):
        obj = getattr(self.module, item)
        return self._safe(obj) if hasattr(obj, '__call__') else obj

and you can use it like so:

safe_json = SafeInvocator(json)
text = "{'foo':'bar'}"
item = safe_json.loads(text)
if item:
    # do something
世俗缘 2024-11-05 02:18:45

在我看来,JSONDecodeError 是比 ValueError 更好的选择。

可以做类似的事情:

def jsn_check(jsn):
    try:
        in_jsn = json.loads(jsn)
    except (json.decoder.JSONDecodeError) as errh:
        return False
    return True

示例:

import json

jsn = """{
   "value": 30,
   "type": "Tip 3,
   "targetModule": "Target 3",
   "version": 0,
   "systemId": 3}
   
"""

def jsn_check(jsn):
    try:
        in_jsn = json.loads(jsn)
    except (json.decoder.JSONDecodeError) as errh:
        return False
    return True
    
print(jsn_check(jsn))

输出:

False

In my opinion, JSONDecodeError is much better option than ValueError.

Can do something like:

def jsn_check(jsn):
    try:
        in_jsn = json.loads(jsn)
    except (json.decoder.JSONDecodeError) as errh:
        return False
    return True

Example:

import json

jsn = """{
   "value": 30,
   "type": "Tip 3,
   "targetModule": "Target 3",
   "version": 0,
   "systemId": 3}
   
"""

def jsn_check(jsn):
    try:
        in_jsn = json.loads(jsn)
    except (json.decoder.JSONDecodeError) as errh:
        return False
    return True
    
print(jsn_check(jsn))

Output:

False
冷︶言冷语的世界 2024-11-05 02:18:45

try 块中非常简单。然后您可以验证正文是否是有效的 JSON

async def get_body(request: Request):
try:
    body = await request.json()
except:
    body = await request.body()
return body

Much simple in try block. You can then validate if the body is a valid JSON

async def get_body(request: Request):
try:
    body = await request.json()
except:
    body = await request.body()
return body
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文