diff --git a/site/parser.py b/site/parser.py index 4398aad..dfc76ea 100644 --- a/site/parser.py +++ b/site/parser.py @@ -150,8 +150,9 @@ def _parse_pdf(file_bytes: bytes) -> dict: "page": pn, }) - # ── Таблицы: только с рамками ── + # ── Таблицы: с рамками + без рамок ── tables = page.extract_tables() + found_any = False if tables: for tbl in tables: if tbl and _table_has_content(tbl): @@ -160,29 +161,49 @@ def _parse_pdf(file_bytes: bytes) -> dict: "rows": tbl, "page": pn, }) + found_any = True + + # Если рамок нет — пробуем text strategy с жёстким фильтром + if not found_any: + tbl_text = page.extract_tables({ + "vertical_strategy": "text", + "horizontal_strategy": "text", + }) + if tbl_text: + for tbl in tbl_text: + if tbl and _table_has_content(tbl, min_cols=3): + result["elements"].append({ + "type": "table", + "rows": tbl, + "page": pn, + }) except Exception as e: result["errors"].append(f"pdfplumber: {e}") return result -def _table_has_content(tbl: list, min_fill_ratio: float = 0.0) -> bool: +def _table_has_content(tbl: list, min_fill_ratio: float = 0.0, min_cols: int = 0) -> bool: """ Проверить что таблица содержит осмысленные ТАБЛИЧНЫЕ данные. Отбрасываем: - Полностью пустые - - Менее 2 строк (обычно это текст, не таблица) - - Менее 4 заполненных ячеек (слишком мало для таблицы) + - Менее 2 строк + - Менее min_cols колонок (если задано) + - Менее 4 заполненных ячеек - Менее 40% ячеек заполнены """ if not tbl or not tbl[0]: return False - # Одна строка — не таблица, а текст if len(tbl) <= 1: return False + # Проверить минимальное число колонок + if min_cols > 0 and len(tbl[0]) < min_cols: + return False + total = 0 filled = 0 @@ -195,11 +216,9 @@ def _table_has_content(tbl: list, min_fill_ratio: float = 0.0) -> bool: if cell_str: filled += 1 - # Минимум 4 заполненных ячейки if filled < 4: return False - # Не менее 40% ячеек должны быть заполнены if total > 0 and filled / total < 0.4: return False