【问题标题】:Need to get or convert data from a site to be valid JSON需要从站点获取或转换数据为有效的 JSON
【发布时间】:2018-11-11 18:24:05
【问题描述】:

我正在编写一个脚本,该脚本将从网站(Cisco Patches 站点)获取数据,并根据收到的数据,将其发布到另一个站点(ServiceNow 事件管理)。 POST 需要是带有特定键的 REST/JSON 才能工作。

我有足够的代码来获取数据,并且我有代码可以 POST 工作。

我很难将我从 GET 获得的数据转换成有效的 JSON 键值对映射到 POST。

我正在使用以下代码从 Cisco 网站获取新补丁列表。我得到了正确的数据,但如果数据不是我可以使用它以 JSON 格式发布到另一个工具的格式(使用不同的键,但返回信息中的值。

这行得通-

def getjson(ciscourl):
    response = urllib.request.urlopen(ciscourl)
    ciscodata = response.read().decode("utf-8")
    return json.loads(ciscodata)

我得到的数据如下所示(这个查询产生了 2 个补丁):

[{"identifier":"cisco-sa-20180521-cpusidechannel","title":"CPU Side-Channel Information Disclosure Vulnerabilities: May 2018","version":"1.5","firstPublished":"2018-05-22T01:00:00.000+0000","lastPublished":"2018-05-31T20:44:16.123+0000","workflowStatus":null,"id":1,"name":"Cisco Security Advisory","url":"https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20180521-cpusidechannel","severity":"Medium","workarounds":"No","cwe":null,"cve":"CVE-2018-3639,CVE-2018-3640","ciscoBugId":"","status":"Updated","summary":"On May 21, 2018, researchers disclosed two vulnerabilities that take advantage of the implementation of speculative execution of instructions on many modern microprocessor architectures to perform side-channel information disclosure attacks. These vulnerabilities could allow an unprivileged, ","totalCount":6,"relatedResource":[]},{"identifier":"cisco-sa-20180516-firepwr-pb","title":"Cisco Firepower Threat Defense Software Policy Bypass Vulnerability","version":"1.0","firstPublished":"2018-05-16T16:00:00.000+0000","lastPublished":"2018-05-16T16:00:00.000+0000","workflowStatus":null,"id":1,"name":"Cisco Security Advisory","url":"https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20180516-firepwr-pb","severity":"Medium","workarounds":"No","cwe":"CWE-693","cve":"CVE-2018-0297","ciscoBugId":"CSCvg09316","status":"New","summary":"A vulnerability in the detection engine of Cisco Firepower Threat Defense software could allow an unauthenticated, remote attacker to bypass a configured Secure Sockets Layer (SSL) Access Control (AC) policy to block SSL traffic.The vulnerability is due to the incorrect handling ","totalCount":6,"relatedResource":[]}]

我可以从中提取值,例如print(jarray.get('identifier')),但我很难使用我定义的键将这些值映射到我自己的 JSON 映射中。因此,我返回的键 identifier 的值需要映射到我的 JSON 映射中名为 "node" 的键。

我试过json.loadsjson.loadjson.dumpjson.dumps。每次错误都是属性类型错误。

这是我感到困惑的代码:

def createJson(l):
#try:

    jsonarray = l
    o_source = "CiscoUpdatePatchChecker"
    o_node = (jsonarray.get('identifier')) #this does not work
    o_metric_name = ("Critical")
    o_type = ("test")
    o_resource = ("test_resource")
    o_description = jsonarray  #this works
    o_event_class = ("test event class")
    o_additional_info = jsonarray
    print ("-" * 50)
    print (o_source, o_node, o_metric_name, o_type, o_resource, o_description, o_event_class, o_additional_info)
    print ("-" * 50)
    data = {"source": o_source, "node": o_node, "metric_name": o_metric_name, "type": o_type, "resource": o_resource, "event_class": o_event_class, "description": o_description, "additional_info": o_additional_info}
    return json.dumps(data)
# except:
    #pass

除此之外,其余代码只是将数据发布到正在运行的 ITSM。 -

def postjson(data):
    # try:
    url = posturl
    auth = HTTPBasicAuth(username, password)
    head = {'Content-type': 'application/json',
            'Accept': 'application/json'}
    payld = data
    ret = requests.post(url, auth=auth , data=payld, headers=head)
    # sys.stdout.write(ret.text)
    returned_data = ret.json()
    print(returned_data)

所以我的问题是将要返回的数据映射到 JSON 映射中的键:值对,并且我需要循环代码的次数与检索到的补丁数量一样多。我目前正计划在我的 main 函数中循环需要 POST 的 JSON 映射的数量。

现在,我只是获取我获得的所有数据并将我获得的所有数据映射到"description""additional_info" 字段。这行得通,我可以很好地发布数据。

如果有人能指出如何处理我从 GET 请求中获得的数据的示例,这将对我有很大帮助。

【问题讨论】:

    标签: python json python-3.x rest


    【解决方案1】:

    json.loads(ciscodata) 返回一个字典数组。

    o_node = (jsonarray.get('identifier')) 语句失败,因为它试图在jsonarray 是一个列表时获取字典键。

    试试o_node = jsonarray[0].get('identifier')

    我不确定你为什么在 jsonarray 周围有括号——那些不应该在那里。

    一般来说,你可以这样做:

    for elem in jsonarray:
        identifier = elem.get('identifier')
        title = elem.get('title')
        ... etc
        do_something(identifier, title, ...)
    

    这使得调试更容易,因为您可以测试从 api 调用返回的值。

    如果您总是在字典中获得相同的键,则可以跳过此分配并直接执行

    for elem in jsonarray:
        do_something(elem.get('key1'), elem.get('key2'), ...)`
    

    希望有帮助

    【讨论】:

    • 谢谢!这就是我前进所需要的。我现在将 dict 中的数据映射到我的键值对中。键总是相同的,所以我会按照你的第二个例子。
    猜你喜欢
    • 2016-05-19
    • 2022-07-18
    • 2017-03-10
    • 2012-08-27
    • 1970-01-01
    • 1970-01-01
    • 2020-02-22
    • 1970-01-01
    • 2021-12-01
    相关资源
    最近更新 更多