Создайте дерево процессов формы json файл. в питоне

1

Мне нужна помощь по несколько простой проблеме.

Я пытаюсь преобразовать содержимое json файла из этого:

    {   "Timestamp": "Timestamp",
        "name": "SVCHOST.EXE",
        "icon": "binary_icon.png",
        "Process": SVCHOST.EXE,
        "Pid": "876",
        "PPID": "500"],
        "children": [Process details])
    },
    {   "Timestamp":"Timestamp",
        "name": "LSAS.EXE",
        "icon": "binary_icon.png",
        "Process": "LSAS.EXE",
        "Pid": "500",
        "PPID": "4"],
        "children": [Process details])
    },
    {   "Timestamp":"Timestamp",
        "name": "SYSTEM",
        "icon": "binary_icon.png",
        "Process": "SYSTEM",
        "Pid": "4",
        "PPID": "0"],
        "children": [Process details])
    }

К этому:

{
"name": "Root", 
"children": [
    {
        "name": "4", 
        "children": [
            {
                "name": "500", 
                "children": [
                    {
                        "name": "876", 
                        "children": []
                    }
                ]
            }
        ]
    }
}

Для создания графа дерева узлов в конце.

Но после большого количества проб и ошибок, и все же не близко к результату, который мне нужен. Я прошу указать какой-нибудь указатель, советы или трюки. Буду признателен за любую оказанную помощь.

Спасибо,

Вот моя последняя попытка.

import json

links = ({
"Timestamp": "Timestamp",
    "name": "SVCHOST.EXE",
    "icon": "binary_icon.png",
    "Process": "SVCHOST.EXE",
    "Pid": "876",
    "PPID": "500",
    "children": "Process_details"
},
  {
    "Timestamp":"Timestamp",
    "name": "LSAS.EXE",
    "icon": "binary_icon.png",
    "Process": "LSAS.EXE",
    "Pid": "500",
    "PPID": "4",
    "children": "Process_details"
},
  {
    "Timestamp":"Timestamp",
    "name": "SYSTEM",
    "icon": "binary_icon.png",
    "Process": "SYSTEM",
    "Pid": "4",
    "PPID": "0",
    "children": "Process_details"
})



parent_proc_node = {}
root = {'name': 'Root', 'children': []}
for item in procs:
    parent_node = parent_proc_node.get(item['Pid'])
    if not parent_node:
        parent_proc_node[item['Pid']] = parent_node = {'name': item['PPID']}
        root['children'].append(parent_node)
    parent_proc_node[item['PPID']] = child_node = {'name': item['Pid']}
    parent_node.setdefault('children', []).append(child_node)

print json.dumps(root, indent=4)

Токовый выход:

{
"name": "Root", 
"children": [
    {
        "name": "500", 
        "children": [
            {
                "name": "876", 
                "children": [
                    {
                        "name": "500", 
                        "children": [
                            {
                                "name": "4"
                            }
                        ]
                    }
                ]
            }
        ]
    }
}

Результат теперь то, что я хочу, но им все еще не удается правильно сопоставить родительский процесс с дочерними элементами. Что я делаю неправильно?

Правильный вывод будет следующим:

{
"name": "Root", 
"children": [
    {
        "name": "4", 
        "children": [
            {
                "name": "500", 
                "children": [
                    {
                        "name": "876", 
                        "children": [
                            {
                                "name": ""
                            }
                        ]
                    }
                ]
            }
        ]
    }
}
  • 0
    Ваши входные и выходные данные выглядят немного странно. Например, ] после «PPID» выглядят неправильно. Что случилось с соответствием [ ?
  • 0
    Извините, это плохо, мне пришлось удалить информацию, чувствительную к системе, из файла json.
Показать ещё 6 комментариев
Теги:
treeview
process

2 ответа

1
Лучший ответ

Вот какой код, который делает то, что я думаю, вы хотите. Он обрабатывает links (которые я превратил в список, поскольку JSON не имеет кортежей), преобразовывая его в вложенную структуру, которую вы показываете как окончательный корректный вывод. Я также добавил несколько новых записей, чтобы у некоторых родителей было несколько детей.

Хитрость заключается в том, чтобы сначала создать словарь (ids), который фиксирует отношения родитель-потомок идентификаторов процессов.

import json

links = [
    {
        "Timestamp": "Timestamp",
        "name": "SVCHOST.EXE",
        "icon": "binary_icon.png",
        "Process": "SVCHOST.EXE",
        "Pid": "876",
        "PPID": "500",
        "children": "Process_details"
    },
    {
        "Timestamp": "Timestamp",
        "name": "LSAS.EXE",
        "icon": "binary_icon.png",
        "Process": "LSAS.EXE",
        "Pid": "500",
        "PPID": "4",
        "children": "Process_details"
    },
    {
        "Timestamp": "Timestamp",
        "name": "LSAS.EXE",
        "icon": "binary_icon.png",
        "Process": "LSAS.EXE",
        "Pid": "510",
        "PPID": "4",
        "children": "Process_details"
    },
    {
        "Timestamp": "Timestamp",
        "name": "LSAS.EXE",
        "icon": "binary_icon.png",
        "Process": "LSAS.EXE",
        "Pid": "600",
        "PPID": "510",
        "children": "Process_details"
    },
    {
        "Timestamp": "Timestamp",
        "name": "SYSTEM",
        "icon": "binary_icon.png",
        "Process": "SYSTEM",
        "Pid": "4",
        "PPID": "0",
        "children": "Process_details"
    }
]

# Create a dict linking each pid to its parent
ids = {}
for d in links:
    # Use "0" as the ppid if "PPID" field is an empty string 
    ppid, pid = d["PPID"] or "0", d["Pid"]
    ids.setdefault(ppid, []).append(pid)
print(ids)

# Nest the data for each pid in its parent dict
def insert(lst, ppid, name):
    if ppid in ids:
        children = []
        lst.append({"name": name, "children": children})
        for pid in ids[ppid]:
            insert(children, pid, pid)
    else:
        children = [{"name": ""}]
        lst.append({"name": name, "children": children})

nested = []
insert(nested, "0", "Root")
print(json.dumps(nested[0], indent=4))

выход

{'500': ['876'], '4': ['500', '510'], '510': ['600'], '0': ['4']}
{
    "name": "Root",
    "children": [
        {
            "name": "4",
            "children": [
                {
                    "name": "500",
                    "children": [
                        {
                            "name": "876",
                            "children": [
                                {
                                    "name": ""
                                }
                            ]
                        }
                    ]
                },
                {
                    "name": "510",
                    "children": [
                        {
                            "name": "600",
                            "children": [
                                {
                                    "name": ""
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}
  • 0
    Спасибо, это почти решает проблему :) Теперь остается только одна проблема - вызов функции вставки с префиксом pid не будет работать. Когда я запускаю приведенный выше код, на дату выборки вкладываются только дочерние процессы для PPID 0.
  • 0
    @Jmik Я не знаю, что ты имеешь в виду под "префиксом pid". Функция insert опирается на структуру в ids представляющую собой связанное дерево, и вам нужно вызвать insert с корневым узлом этого дерева. Если у вас есть несколько деревьев, вам придется проделать еще немного работы, чтобы справиться с этим.
Показать ещё 2 комментария
0

@PM 2Ring Извините, пожалуйста, обратите внимание на замечания PPID 0. Отсутствие обработки выполнения на моем конце. :) Ваш эскрипт отлично работает, для родителей с детьми. однако, если PID не имеет родителя, он не добавляется в корневой узел.

procs = [{
  "Timestamp": "Timestamp",
        "name": "SVCHOST.EXE",
        "icon": "binary_icon.png",
        "Process": "SVCHOST.EXE",
        "Pid": "876",
        "PPID": "500",
        "children": "Process_details"
    },
      {
        "Timestamp":"Timestamp",
        "name": "LSAS.EXE",
        "icon": "binary_icon.png",
        "Process": "LSAS.EXE",
        "Pid": "500",
        "PPID": "4",
        "children": "Process_details"
    },
      {
        "Timestamp":"Timestamp",
        "name": "SYSTEM",
        "icon": "binary_icon.png",
        "Process": "SYSTEM",
        "Pid": "4",
        "PPID": "0",
        "children": "Process_details"
}
,
  {
    "Timestamp":"Timestamp",
    "name": "ROUGEPROC",
    "icon": "binary_icon.png",
    "Process": "ROUGEPROC",
    "Pid": "4322",
    "PPID": "",
    "children": "Process_details"
}]

# Create a dict linking each pid to its parent
ids = {}
for d in procs:
    ppid, pid = d["PPID"], d["Pid"]
    ids.setdefault(ppid, []).append(pid)
print(ids)

# Nest the data for each pid in its parent dict
def insert(lst, ppid, name):
    if ppid in ids:
        children = []
        lst.append({"name": name, "children": children, "icon": "binary_icon.png"})
        for pid in ids[ppid]:
            insert(children, pid, pid)
    else:
        children = []
        lst.append({"name": name, "children": children, "icon": "binary_icon.png"})

nested = []

insert(nested, "0", "PPID")
proc_report = {"name" :"HOSTNAME",
                        "icon": "win_os_icon.png",
                         "children": nested[0]["children"]
                         }
print(json.dumps(proc_report, indent=4))

Выход:

{'': ['4322'], '0': ['4'], '4': ['500'], '500': ['876']}
{
    "children": [
        {
            "icon": "binary_icon.png", 
            "name": "4", 
            "children": [
                {
                    "icon": "binary_icon.png", 
                    "name": "500", 
                    "children": [
                        {
                            "icon": "binary_icon.png", 
                            "name": "876", 
                            "children": []
                        }
                    ]
                }
            ]
        }
    ], 
    "name": "HOSTNAME", 
    "icon": "win_os_icon.png"
}
  • 0
    «если PID не имеет родителя, он не добавляется в корневой узел». С этим достаточно легко иметь дело. Если в цикле for d in links: поле «PPID» равно «», тогда преобразуйте его в «0», например, ppid, pid = d["PPID"] or "0", d["Pid"]
  • 0
    очень верно, и работает :) И спасибо за помощь / терпение, в последние пару дней слепая на меня.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню