Условное извлечение данных из вложенного JSON с использованием рекурсивного поиска не возвращает непустые конкретные знаPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Условное извлечение данных из вложенного JSON с использованием рекурсивного поиска не возвращает непустые конкретные зна

Сообщение Anonymous »

Я работаю над сценарием Python для извлечения определенных значений из (несколько 100 000) глубоко вложенных файлов JSON. Хотя мой сценарий правильно извлекает большинство нужных полей с помощью рекурсивного поиска, он не может правильно обрабатывать условное извлечение, указанное в словаре CONDITIONAL_EXTRACTIONS. В частности, я пытаюсь:
Извлечь cna.descriptions.value, только если соответствующий cna.descriptions.lang находится в ['en', 'eng', ' english'].
Извлекайте cna.problemTypes.descriptions.description, только если соответствующий cna.problemTypes.descriptions.lang находится в ['en', 'eng', 'english'].
Верните True для ключа is_kev, только если metrics.other.type равен 'kev'.
Пример структуры JSON:

Код: Выделить всё

{
"containers": {
"cna": {
"descriptions": [
{"lang": "en", "value": "English description"},
{"lang": "fr", "value": "Description en français"}
],
"problemTypes": [
{
"descriptions": [
{"lang": "en", "description": "Cross-site Scripting (XSS)"},
{"lang": "de", "description": "Deutscher Text"}
]
}
]
}
},
"metrics": {
"other": {"type": "kev"}
}
}
Контекст кода:
Я использую следующую структуру, чтобы определить, что нужно извлечь:

Код: Выделить всё

EXTRACTIONS = {
'cve_id': ['cveMetadata.cveId'],
... # There's a bunch more keys I'm trying to extract
'cve_desc': ['cna.descriptions'],
'cwe_desc': ['cna.problemTypes.descriptions'],
'is_kev': ['metrics.other.type']
}

CONDITIONAL_EXTRACTIONS = {
'cve_desc': {
'paths': ['cna.descriptions'],
'condition': lambda _, full_data: [
desc.get('value').strip() for desc in full_data
.get('cna', {}).get('descriptions', [])
if desc.get('lang').strip().lower() in ['en', 'eng', 'english']
]
},
'cwe_desc': {
'paths': ['cna.problemTypes.descriptions'],
'condition': lambda _, full_data: [
desc.get('description').strip() for cwe in full_data
.get('cna', {}).get('problemTypes', [])
for desc in cwe.get('descriptions', [])
if desc.get('lang').strip().lower() in ['en', 'eng', 'english']
]
},
'is_kev': {
'paths': ['metrics.other.type'],
'condition': lambda value, _: value == 'kev'
}
}
Функция извлечения предназначена для применения указанных условий там, где это необходимо, и вызывается в методеprocess_files моего класса JSONParser:

Код: Выделить всё

def deep_search(data, target_keys, condition=None):
results = []

def recursive_search(current_data, keys, full_data):
if not keys or not isinstance(current_data, (dict, list)):
return None
current_key = keys[0]

if isinstance(current_data, dict):
if current_key in current_data:
value = current_data[current_key]
if len(keys) == 1:
if isinstance(value, list) and condition:
results.extend(condition(None, full_data))
elif condition is None or condition(value, full_data):
results.append(value)
else:
recursive_search(current_data[current_key], keys[1:], full_data)
for value in current_data.values():
recursive_search(value, keys, full_data)
elif isinstance(current_data, list):
for item in current_data:
recursive_search(item, keys, full_data)

for key_path in target_keys:
keys = key_path.split('.')
recursive_search(data, keys, data)

return results[0] if len(results) == 1 else results or pd.NA

def extract_file_data(
file_path: str,
extraction_mapping: Dict[str, List[str]]
) -> Dict[str, Any]:
""" Extract relevant data from a single JSON file.  """
try:
with open(file_path, 'r', encoding='utf-8') as file:
data = json.load(file)
# Extract data using deep search
extracted_data = {}
for key, paths in extraction_mapping.items():
# Handle conditional extractions
if key in CONDITIONAL_EXTRACTIONS:
condition_info = CONDITIONAL_EXTRACTIONS[key]
condition = condition_info.get('condition')
result = deep_search(data, condition_info['paths'], condition)
else:
# Perform unconditional search for each key
result = deep_search(data, paths)
extracted_data[key] = result
print(f"Key: {key}, Paths: {paths}, Result: {result}")
# Return the extracted data
return extracted_data
except Exception as e:
print(f'Error processing {file_path}: {e}')
return {}

Функция deep_search работает правильно для безусловного извлечения, но не может правильно применить условия или вернуть правильные результаты для CONDITIONAL_EXTRACTIONS. Например:
Для cve_desc и cwe_desc функция ничего не возвращает, и для меня это не имеет смысла.
Для is_kev, условие возвращает фактическое значение «kev» и None вместо True или False.
Операторы печати в deep_search показывают «Значения» для этих условий. клавиши, расположенные на один уровень выше значение, которое я ищу, которое соответствует тому, что я ожидаю, поскольку лямбда-функция использует методы get с этого уровня для поиска нужных ключей, однако операторы печати extract_file_data подтверждают, что результаты Нет.

Подробнее здесь: https://stackoverflow.com/questions/793 ... ils-to-ret
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Почему «разделить» на пустой строке возвращает непустые массивы?
    Anonymous » » в форуме JAVA
    0 Ответы
    1 Просмотры
    Последнее сообщение Anonymous
  • Алгоритм рекурсивного поиска всегда возвращает false
    Anonymous » » в форуме Php
    0 Ответы
    18 Просмотры
    Последнее сообщение Anonymous
  • Проверяйте только непустые поля
    Anonymous » » в форуме JAVA
    0 Ответы
    11 Просмотры
    Последнее сообщение Anonymous
  • Проверьте, есть ли в многомерном массиве непустые листовые узлы.
    Anonymous » » в форуме Php
    0 Ответы
    20 Просмотры
    Последнее сообщение Anonymous
  • Заменить все непустые струны в столбце на постоянную
    Anonymous » » в форуме Python
    0 Ответы
    5 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»