#python #json
#python #json
Вопрос:
Я хочу создать файл JSON с помощью Python. Структура JSON выглядит следующим образом :
{
"index_pattern" : "all_packets"
"packets" : [
{
"packet_type" : "TCP"
"source_ip" : "192.168.0.2",
"destination_ip" : "192.168.0.114"
},
{
"packet_type" : "ICMP"
"source_ip" : "192.168.0.2",
"destination_ip" : "192.168.0.114"
}
]
}
Всякий раз, когда я перехватываю пакет с помощью модуля wireshark, я хочу добавить этот пакет, скажем, в файл myoutput.json. Проблема в том, что используется что-то вроде
f = open("myoutput.json", "a")
f.write({
"packet_type" : "ICMP"
"source_ip" : "192.168.0.2",
"destination_ip" : "192.168.0.114"
})
не подходит, потому что у меня нет изящного завершения работы, и я не могу добавить необходимый завершающий параграф для завершения JSON. Итак, мне нужно записать между массивом пакетов. Каков наилучший способ добиться этого.
Комментарии:
1. Не могли бы вы вместо этого сохранить это в базе данных NoSQL и просто отправить пакеты туда?
2. Привет, спасибо за внимание. Моим требованием к проекту является создание файла JSON в качестве выходных данных, которые может прочитать другая программа (скажем, X). И программа X уже использует ElasticSearch, поэтому мы можем не включать в проект другой инструмент хранения. Вот почему я, мы не можем догадаться. @doctorlove
Ответ №1:
При записи файла:
import json
with open('myoutput.json', 'a') as fo:
json.dump({
"packet_type" : "ICMP",
"source_ip" : "192.168.0.2",
"destination_ip" : "192.168.0.114"
}, fo)
При чтении файла выполните:
with open('myoutput.json') as fo:
data = fo.read()
data = data.replace('}{', '},{')
data = '[' data ']'
data = json.loads(data)
result = {"index_pattern" : "all_packets",
"packets": data}
Редактировать
Вы также можете создать вспомогательный класс для этого:
import json
class WriteObject:
def __init__(self, fname='myoutput.json'):
self.fname = fname
def push(self, data):
# data_example={
# "packet_type" : "ICMP",
# "source_ip" : "192.168.0.2",
# "destination_ip" : "192.168.0.114"
# }
with open(self.fname, 'a') as fo:
json.dump(data, fo)
def get_all(self):
with open(self.fname) as fo:
data = fo.read()
data = data.replace('}{', '},{')
data = '[' data ']'
data = json.loads(data)
result = {"index_pattern" : "all_packets",
"packets": data}
return result
# usage
obj = WriteObject()
obj.push({
"packet_type" : "ICMP",
"source_ip" : "192.168.0.2",
"destination_ip" : "192.168.0.114"
})
Комментарии:
1. Но вы действительно проверяли, работает ли ваш код?
2. @taras, Да, в Jupyter!
3. Привет, спасибо за ответ. Чтобы было более понятно, я хочу выполнить операцию push в поле packets, которое находится в файле. Просто чтобы продемонстрировать, что это такое, myoutput.json[«пакеты»].push({ «packet_type»: «ICMP», «source_ip»: «192.168.0.2», «destination_ip»: «192.168.0.114» })
4. Решение с реализацией класса решило это. Спасибо всем вам <3
Ответ №2:
Одним из возможных решений является json.load
перенос всего файла, скажем, в объект python data
и добавление packet
к data["packets"]
. Затем вам нужно записать обновленный data
обратно в ваш json-файл.
Недостатком этого подхода является необходимость постоянного чтения и записи данных в json-файл.
Это можно улучшить, объединив список пакетов (таким образом, вы временно сохраняете свои пакеты в packets
списке) и обновляя файл json только тогда, когда он достигает некоторого предопределенного размера (скажем, когда len(packets) == 20
). После этого вы можете очистить его packets
и снова начать собирать в него данные.