diff --git a/parse_pol177.py b/parse_pol177.py index 53b3f1a..f499671 100644 --- a/parse_pol177.py +++ b/parse_pol177.py @@ -1,73 +1,127 @@ #!/usr/bin/env python3 """ -Parse PDF document using unstructured-api on 192.168.1.103. -Uses maximum quality settings (hi_res + yolox model). -Saves parsed JSON to /tmp/pol177_parsed.json. +Парсинг ПОЛ-177 через Unstructured API: +- Текст: Unstructured API (192.168.1.103:8005) +- Таблицы: Unstructured API (element_type=Table, strategy=hi_res) + +Сохраняет результат в /opt/okf-regulations/concepts/pol177_parsed.json """ - -import requests import json -import sys +import subprocess +from pathlib import Path -PDF_PATH = "/opt/documents_xk/АОХКСибцем/07 Служба Вице-президента по экономике и финансам/ДИТ/02 Регламенты деятельности/10 Положение Хранение электронных документов от 03.04.2024 № ПОЛ-177.pdf" -API_URL = "http://192.168.1.103:8005/general/v0/general" +# === НАСТРОЙКИ === +UNSTRUCTURED_API = "http://192.168.1.103:8005/general/v0/general" +PDF_PATH = "/opt/documents_xk/АОХКСибцем/07 Служба Вице-президента по экономике и финансам/ДИТ/02 Регламенты деятельности/08 Положение Управление ИТ-инцидентами от 20.02.2024 № ПОЛ-123-2.pdf" +OUTPUT_PATH = "/opt/okf-regulations/concepts/pol123_parsed.json" -def parse_pdf(): - print("Parsing PDF with maximum quality (hi_res + yolox)...") +def fetch_unstructured(pdf_path: str, strategy: str = "hi_res", element_type: str = None) -> list[dict]: + """Получаем элементы из Unstructured API. - # Maximum quality parameters - form_data = { - 'strategy': 'hi_res', - 'hi_res_model_name': 'yolox', - 'pdf_infer_table_structure': 'true', - 'extract_images': 'true', - 'extract_image_block_types': '["image", "table"]', - } + Args: + pdf_path: путь к PDF + strategy: hi_res для таблиц, fast для текста + element_type: фильтр по типу (None = все, 'Table' = только таблицы) + """ + cmd = [ + "curl", "-X", "POST", UNSTRUCTURED_API, + "-F", f"files=@{pdf_path}", + "-F", f"strategy={strategy}", + "-F", "output_format=application/json", + "-F", "coordinates=true", + ] + if element_type: + cmd.extend(["-F", f"element_types=[{element_type}]"]) - with open(PDF_PATH, 'rb') as f: - # Note: 'files' (plural) - API expects list of UploadFile - files = {'files': f} - response = requests.post(API_URL, files=files, data=form_data) + result = subprocess.run(cmd, capture_output=True, text=True) + if result.returncode != 0: + print(f" ❌ Unstructured API error: {result.stderr}") + return [] + data = json.loads(result.stdout) + if isinstance(data, list): + return data + return data.get("elements", []) + +def extract_tables(pdf_path: str) -> list[dict]: + """Извлекаем таблицы через Unstructured API и фильтруем по типу + HTML.""" + print(" Запрос всех элементов через Unstructured API (strategy=hi_res)...") + elements = fetch_unstructured(pdf_path, strategy="hi_res", element_type=None) - if response.status_code != 200: - print(f"ERROR: API returned {response.status_code}: {response.text[:500]}") - sys.exit(1) - - result = response.json() - - # API returns array directly, not {"elements": [...]} - if isinstance(result, list): - elements = result - else: - elements = result.get('elements', []) - - print(f"Extracted {len(elements)} elements") - - # Add page numbers - for i, el in enumerate(elements): - if 'page_number' in el.get('metadata', {}): - el['page_number'] = el['metadata']['page_number'] - else: - el['page_number'] = i + 1 - - # Save to JSON - output = { - 'filename': '10 Положение Хранение электронных документов от 03.04.2024 № ПОЛ-177.pdf', - 'total_elements': len(elements), - 'elements': elements - } - - with open('/tmp/pol177_parsed.json', 'w', encoding='utf-8') as f: - json.dump(output, f, ensure_ascii=False, indent=2) - - print(f"Saved {len(elements)} elements to /tmp/pol177_parsed.json") - - # Stats - types = {} + real_tables = [] for el in elements: - t = el.get('type', 'Unknown') - types[t] = types.get(t, 0) + 1 - print(f"Element types: {types}") + # Фильтр 1: тип должен быть Table + if el.get("type") != "Table": + continue + + meta = el.get("metadata", {}) + text = el.get("text", "") + html = meta.get("text_as_html", "") + + # Фильтр 2: должен быть HTML-представление (настоящая таблица) + if not html or "
| ]*>| | ]*>', html[:500], re.IGNORECASE) + if trs: + row_count = len(trs) + if first_tr: + col_count = len(first_tr) + + table_data = { + "page": meta.get("page_number"), + "text": text, + "html": html, + "row_count": row_count, + "col_count": col_count, + } + real_tables.append(table_data) + + return real_tables + +def extract_text(pdf_path: str) -> list[dict]: + """Извлекаем текст через Unstructured API (strategy=fast).""" + print(" Запрос текста через Unstructured API (strategy=fast)...") + elements = fetch_unstructured(pdf_path, strategy="fast") + return elements + +def main(): + print("=" * 60) + print("📄 Парсинг ПОЛ-177") + print("=" * 60) + + # 1. Текст + print("\n[1/3] Извлечение текста (strategy=fast)...") + text_elements = extract_text(PDF_PATH) + print(f" ✅ Получено {len(text_elements)} элементов") + + # 2. Таблицы + print("\n[2/3] Извлечение таблиц (element_type=Table)...") + tables = extract_tables(PDF_PATH) + print(f" ✅ Найдено {len(tables)} таблиц") + + # 3. Сохраняем результат + result = { + "document": "ПОЛ-123", + "title": "Положение Управление ИТ-инцидентами от 20.02.2024 № ПОЛ-123-2", + "text": text_elements, + "tables": tables, + "metadata": { + "unstructured_api": UNSTRUCTURED_API, + "strategy_text": "fast", + "strategy_tables": "hi_res", + "timestamp": "2026-07-06", + }, + } + + Path(OUTPUT_PATH).write_text(json.dumps(result, ensure_ascii=False, indent=2)) + print(f"\n✅ Сохранено в {OUTPUT_PATH}") + print("=" * 60) + +if __name__ == "__main__": + main() |
|---|