fix(sf): pravo.gov66 law_type числовой код =1 Постановление (#1062) #1149

Merged
bot-reviewer merged 1 commit from fix/reservation-pravo-selectors into main 2026-06-07 14:17:53 +00:00
2 changed files with 18 additions and 3 deletions

View file

@ -28,8 +28,12 @@ _SEARCH_URL = f"{_BASE_URL}/search/"
# Тайм-аут щедрый: сервер иногда медленный.
_TIMEOUT = httpx.Timeout(60.0, connect=15.0)
# Числовые коды типов документов (select#id_law_type на сайте).
# Текстовое значение «Постановление» — неверный параметр, сервер не матчит → 0 хитов.
_LAW_TYPE_POSTANOVLENIE = "1" # Постановление Правительства Свердловской области
# Паттерны для извлечения ссылок.
# Числовой doc_id в пути: /35496/
# Числовой doc_id в пути: /35496/ (НЕ /documents/35496/ — у сайта такой структуры нет).
_RE_DOC_PATH = re.compile(r"^/(\d+)/$")
# PDF в /media/pravo/ (не ecp-вариант: ecp — подписанная копия, не всегда парсится).
_RE_PDF_PATH = re.compile(r"/media/pravo/(?!ecp/)[^\s\"']+\.pdf", re.IGNORECASE)
@ -39,14 +43,16 @@ _RE_PDF_ECP_PATH = re.compile(r"/media/pravo/ecp/[^\s\"']+\.pdf", re.IGNORECASE)
def search_documents(
query: str,
law_type: str = "Постановление",
law_type: str = _LAW_TYPE_POSTANOVLENIE,
since: str | None = None,
) -> list[dict[str, Any]]:
"""Поиск документов на pravo.gov66.ru.
Args:
query: поисковый запрос (2-3 слова; 1 или 4+ слов 0 результатов на сервере).
law_type: тип документа, напр. «Постановление».
law_type: числовой код типа документа (см. select#id_law_type). По умолчанию
``_LAW_TYPE_POSTANOVLENIE="1"`` (Постановление). НЕ передавать текст вроде
«Постановление» сервер игнорирует нечисловые коды 0 хитов.
since: дата начала периода в формате «DD.MM.YYYY» (поле signed_start_date).
Returns:
@ -161,6 +167,7 @@ def fetch_pdf(url: str) -> bytes:
__all__ = [
"_LAW_TYPE_POSTANOVLENIE",
"fetch_pdf",
"get_document_pdf_url",
"search_documents",

View file

@ -7,6 +7,7 @@
from __future__ import annotations
from app.services.scrapers.pravo_gov66_client import (
_LAW_TYPE_POSTANOVLENIE,
_extract_pdf_url,
_parse_search_html,
)
@ -94,6 +95,13 @@ _DOC_HTML_NO_PDF = """
"""
class TestLawTypeConstant:
def test_postanovlenie_is_numeric_string(self) -> None:
"""Числовой код — сервер игнорирует текстовые значения типа «Постановление»."""
assert _LAW_TYPE_POSTANOVLENIE == "1"
assert _LAW_TYPE_POSTANOVLENIE.isdigit()
class TestParseSearchHtml:
def test_extracts_doc_ids_and_titles(self) -> None:
results = _parse_search_html(_SEARCH_HTML_FIXTURE)