Python,jsonpath_ng : Exception: Parse error at 1:4 near token ?(?)

标签 python json json-path-expression

如何通过文本字段输入从 JSON 获取特定信息列表?

这是我的示例 JSON 数据(通过 URL 检索)。实际上,有数百项。

{
"items": [
    {
        "timestamp": "2020-04-03T23:24:27+08:00",
        "carpark_data": [
            {
                "carpark_info": [
                    {
                        "total_lots": "91",
                        "lot_type": "C",
                        "lots_available": "36"
                    }
                ],
                "carpark_number": "HE12",
                "update_datetime": "2020-04-03T23:23:34"
            },
            {
                "carpark_info": [
                    {
                        "total_lots": "583",
                        "lot_type": "C",
                        "lots_available": "474"
                    }
                ],
                "carpark_number": "HLM",
                "update_datetime": "2020-04-03T23:23:23"
            },
            {
                "carpark_info": [
                    {
                        "total_lots": "322",
                        "lot_type": "C",
                        "lots_available": "126"
                    }
                ],
                "carpark_number": "RHM",
                "update_datetime": "2020-04-03T23:23:35"
            },
            {
                "carpark_info": [
                    {
                        "total_lots": "97",
                        "lot_type": "C",
                        "lots_available": "85"
                    }
                ],
                "carpark_number": "BM29",
                "update_datetime": "2020-04-03T23:23:43"
            },
            {
                "carpark_info": [
                    {
                        "total_lots": "96",
                        "lot_type": "C",
                        "lots_available": "75"
                    }
                ],
                "carpark_number": "Q81",
                "update_datetime": "2020-04-03T23:23:21"
            },
            {
                "carpark_info": [
                    {
                        "total_lots": "173",
                        "lot_type": "C",
                        "lots_available": "55"
                    }
                ],
                "carpark_number": "C20",
                "update_datetime": "2020-04-03T23:23:24"
            }

        ]
    }
]}

我正在编写以下代码,以便当用户在文本字段中输入相应的 carpark_number 时获取 carpark_data,例如:HLM

我的预期输出是

[
  {
    "carpark_info": [
      {
        "total_lots": "583",
        "lot_type": "C",
        "lots_available": "474"
      }
    ],
    "carpark_number": "HLM",
    "update_datetime": "2020-04-03T23:23:23"
  }
]

我一直在尝试如下,但不确定是否可能..

from kivymd.uix.dialog import MDInputDialog
from urllib import parse
from kivy.network.urlrequest import UrlRequest
from kivy.app import App
import json
from jsonpath_ng import jsonpath,parse


class SearchMenu(MDInputDialog):
   title = 'Search by Address'
   text_button_ok = 'Search'

   def __init__(self):
       super().__init__()
       self.size_hint = [.9, .3]
       self.events_callback = self.callback

   def callback(self,*args):
       address = self.text_field.text
       self.get()
       print(address)

   def get(self):
       url= "https://api.data.gov.sg/v1/transport/carpark-availability"
       UrlRequest(url,on_success=self.success, on_failure=self.failure, on_error=self.error)


   def success(self,urlrequest, result):
       print("ok")
       data=[match.value for match in parse(('$..carpark_data[?(@.carpark_number =address)]')).find(result)]
       json_data=json.dumps(data, indent =2 ,separators=(',', ':'))
       print(json_data)

   def failure(self,urlrequest, result):
       print(result)
       print("failure")

   def error(self,urlrequest, result):
       print(result)
       print("error")

最佳答案

好问题。我认为你们很接近;使用此代码对我有用:

import json
from jsonpath_ng import jsonpath
from jsonpath_ng.ext import parse
json_str = '''{"items":[{"timestamp":"2020-04-03T23:24:27+08:00","carpark_data":[{"carpark_info":[{"total_lots":"91","lot_type":"C","lots_available":"36"}],"carpark_number":"HE12","update_datetime":"2020-04-03T23:23:34"},{"carpark_info":[{"total_lots":"583","lot_type":"C","lots_available":"474"}],"carpark_number":"HLM","update_datetime":"2020-04-03T23:23:23"},{"carpark_info":[{"total_lots":"322","lot_type":"C","lots_available":"126"}],"carpark_number":"RHM","update_datetime":"2020-04-03T23:23:35"},{"carpark_info":[{"total_lots":"97","lot_type":"C","lots_available":"85"}],"carpark_number":"BM29","update_datetime":"2020-04-03T23:23:43"},{"carpark_info":[{"total_lots":"96","lot_type":"C","lots_available":"75"}],"carpark_number":"Q81","update_datetime":"2020-04-03T23:23:21"},{"carpark_info":[{"total_lots":"173","lot_type":"C","lots_available":"55"}],"carpark_number":"C20","update_datetime":"2020-04-03T23:23:24"}]}]}'''
json_obj = json.loads(json_str)
jsonpath_expr = parse('$..carpark_data[?(@.carpark_number == "HLM")]')
print([match.value for match in jsonpath_expr.find(json_obj)])

首先,我认为您的路径查询中存在一些小语法问题/拼写错误

  • 等于运算符实际上是 == (我知道,readme on Github 说明了其他情况!它已经是 reported 了。)
  • 您需要用双引号将搜索字符串括起来,即在您的情况下,它会像这样读取 parse('$..carpark_data[?(@.carpark_number == "'+address+'")]'
  • (此外,您的示例 JSON 缺少结束 } 它可能只在您的帖子中缺失,但在您的代码中不存在,对吗?)

第二,可能是最重要的,在使用路径过滤器[?(..)]时,您需要使用不同的parse导入:

from jsonpath_ng import jsonpath
from jsonpath_ng.ext import parse   

我通过阅读 jsonpath_ng tests 确实发现了这一点在 Github 上并通过反复试验。有趣!

关于Python,jsonpath_ng : Exception: Parse error at 1:4 near token ?(?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61019108/

相关文章:

python - “ float ”对象没有属性 'strip'

python - 如何合并特定的数据框?

json - 很难将 JSON 转换为 Spark Dataframe

json - 动态创建JSON对象

Json 路径 - 对列表列表进行过滤

python - python Tensorflow工作簿执行后取消分配内存

python - 带有夹具预加载的 Django South Schema 迁移

java - Android Volley 空指针异常

java - 如何使用 Jayway JsonPath 等 Java 库添加新的 json 节点