Описание скрипта parser.py

Описание скрипта parser.py

В данном документе будет описан принцип работы данного скрипта.

Для его работы необходимо ввести путь к папке pages

.

Пример:
C:******\Монитор_продаж\pages

Или для монитора продаж, распакованного на диске D :

Скрипт считывает любой путь, независимо от системы, которой пользуется пользователь (Windows, Linux, MacOS).

Для его работы необходим установленный python и pandas.

Первое что делает скрипт, это парсит app.json - составляет нужный пандас датафрейм с необходимыми полями (dataProviders, page_url, page_name)

Далее пробегает по каждому файлу в папке pages,вызывая рекурсивную функцию parse_children.

В данных по ключу children могут быть расположены данные с таким же ключом. Функция parse_children принимает как аргумент целый файл (или фрагмент) и полный путь файла.

Первым делом проверяет наличие таких ключей как ‘children’ и ‘props’.
Затем проверяется ряд условий, необходимые поля добавляются в список строк, затем функция вызывает сама себя передавая в себя объект child.

Таким образом, функция в каждом файле доходит до максимального уровня глубины, пока есть ключи children’, ‘props’, затем переходит к следующему уровню вложенности, а потом и к следующему файлу.

После того, как цикл пройдется по всем файлам и вызовет данную функцию, из строк будет составлен датафрейм, к нему будет будет выполнен джойн ранее созданного датасета.

Сохранение последнего датафрейма будет произведено в ту же папку, где находится исполняемый скрипт.


Сам скрипт можно скопировать тут:
import os
import json
from pprint import pprint
import pandas as pd
from pathlib import Path

path = input('Ввести путь до папки pages: ')
### Пример C:\****\****\****\Монитор_продаж\pages
app_path = Path(path.replace('pages', 'app.json').strip())
path = Path(path.strip())
filenames = os.listdir(path)
rows = []
dataproviders = []

with open(app_path, encoding='utf-8') as ap:
    app_data = json.load(ap)
if 'dataProviders' in app_data:
    for dp in app_data['dataProviders']:
        id = dp['connection']['code']
        dataproviders.append(id)
else: dataproviders.append('none')


def parse_children(data, localfilename):
    if {'children', 'props'} <= set(data):
        for child in data['children']:
            if 'dremioAddons' in child['props']:
                for addon in child['props']['dremioAddons']:
                    addons = []
                    for source in addon['query']['$from']:
                        addons.append(source)
                    rows.append([localfilename, child['type'], '.'.join(addons)])
            if 'dremio' in child['props']:
                addons = []
                sources = child['props']['dremio']
                if type(sources) == list:
                    for query in sources:
                        for addon in query['query']['$from']:
                            addons.append(addon)
                if type(sources) == dict:
                    for addon in sources['query']['$from']:
                        addons.append(addon)
                rows.append([localfilename, child['type'], '.'.join(addons)])
            if 'datasets' in child['props']:
                for dataset in child['props']['datasets']:
                    rows.append([localfilename, child['type'], f'{dataset["query"]["$from"]}.{dataset["name"]}'])
            parse_children(child, localfilename)


for name in filenames:
    row = []
    fullname = path.joinpath(name)
    # fullname = rf'{path}\{name}'
    with open(fullname, encoding='utf-8') as f:
        data = json.load(f)
    ## Обычно в data 1 элемент, но на всякий случай обрабатывается циклом
    for i in data:
        parse_children(i, name)

df = pd.DataFrame(rows, columns=['filename', 'type', 'path'])
df['dataproviders'] = ','.join(dataproviders)
df.to_csv('result.csv', index=False)

1 лайк