domrf_catalog _TextCollector: void-теги (<br>/<img>/<input>) рассинхронизируют стек/буфер — текст блоков теряется #1608

Closed
opened 2026-06-16 17:19:47 +00:00 by bot-backend · 0 comments
Collaborator

Severity: medium · Категория: parsing/data-loss · Файл: backend/app/services/scrapers/domrf_catalog.py:152-186

Файл: backend/app/services/scrapers/domrf_catalog.py:167-186. handle_starttag безусловно делает self._stack.append(...) и self._buf.append('') для любого тега, но HTML5 void-теги (
,,,


,) не вызывают handle_endtag → стек/буфер рассинхронизируются: чужой handle_endtag поп'ает фрейм void-тега, текст всплывает не в тот уровень. Воспроизведено: '
Высота потолков
2,7 м
' → collector.blocks == [] (текст потерян полностью); '
...
' → теряется текст уровня card (внутренний span.price сохраняется). Импакт ограничен: blocks нужны лишь для Шага-3 fallback (ceiling_height_m/section_no, строки 344-362), у которых есть и основной regex-путь по raw HTML. Фикс: в handle_starttag не пушить void-теги в стек/буфер (VOID = {'br','img','input','hr','meta','link','area','base','col','embed','source','track','wbr'}; if tag in VOID: return) либо переопределить handle_startendtag.

Почему баг: Шаг 3 в parse_catalog_flat (fallback для ceiling_height_m и section_no через _find_text_near(blocks, ...)) полагается на корректные blocks. На реальном SSR-HTML DOM.РФ с
// blocks будут пустыми/мусорными, fallback не сработает или даст случайные блоки — поля молча не извлекаются.

Как чинить: Реализовать handle_startendtag (или в handle_starttag не пушить для известных void-тегов: br, img, input, hr, meta, link, area, base, col, embed, source, track, wbr). Либо отслеживать парность тегов и не полагаться на строгий LIFO.


deep-audit backend v2 (после PR #1543) · verify+harden, confidence 0.8 · unit B33

**Severity:** medium · **Категория:** parsing/data-loss · **Файл:** `backend/app/services/scrapers/domrf_catalog.py:152-186` Файл: backend/app/services/scrapers/domrf_catalog.py:167-186. handle_starttag безусловно делает self._stack.append(...) и self._buf.append('') для любого тега, но HTML5 void-теги (<br>,<img>,<input>,<hr>,<meta>) не вызывают handle_endtag → стек/буфер рассинхронизируются: чужой handle_endtag поп'ает фрейм void-тега, текст всплывает не в тот уровень. Воспроизведено: '<div class=a>Высота потолков<br>2,7 м</div>' → collector.blocks == [] (текст потерян полностью); '<div class=card><img><span class=price>...</span></div>' → теряется текст уровня card (внутренний span.price сохраняется). Импакт ограничен: blocks нужны лишь для Шага-3 fallback (ceiling_height_m/section_no, строки 344-362), у которых есть и основной regex-путь по raw HTML. Фикс: в handle_starttag не пушить void-теги в стек/буфер (VOID = {'br','img','input','hr','meta','link','area','base','col','embed','source','track','wbr'}; if tag in VOID: return) либо переопределить handle_startendtag. **Почему баг:** Шаг 3 в parse_catalog_flat (fallback для ceiling_height_m и section_no через _find_text_near(blocks, ...)) полагается на корректные blocks. На реальном SSR-HTML DOM.РФ с <br>/<img>/<input> blocks будут пустыми/мусорными, fallback не сработает или даст случайные блоки — поля молча не извлекаются. **Как чинить:** Реализовать handle_startendtag (или в handle_starttag не пушить для известных void-тегов: br, img, input, hr, meta, link, area, base, col, embed, source, track, wbr). Либо отслеживать парность тегов и не полагаться на строгий LIFO. --- <sub>deep-audit backend v2 (после PR #1543) · verify+harden, confidence 0.8 · unit B33</sub>
bot-backend added the
week ревью 1
label 2026-06-16 17:19:47 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1608
No description provided.