Update parse_pol177.py: use Unstructured API for tables, remove pypdf

This commit is contained in:
Hermes
2026-07-16 17:04:59 +07:00
parent b7e5fffee0
commit f3ecc8cf06
+115 -61
View File
@@ -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", [])
if response.status_code != 200:
print(f"ERROR: API returned {response.status_code}: {response.text[:500]}")
sys.exit(1)
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)
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
if __name__ == '__main__':
parse_pdf()
meta = el.get("metadata", {})
text = el.get("text", "")
html = meta.get("text_as_html", "")
# Фильтр 2: должен быть HTML-представление (настоящая таблица)
if not html or "<table" not in html.lower():
continue
# Извлекаем row/col из HTML
row_count = None
col_count = None
if html:
import re
trs = re.findall(r'<tr[^>]*>', html, re.IGNORECASE)
first_tr = re.findall(r'<td[^>]*>|<th[^>]*>', 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()