cleanup and fix runtime bugs
This commit is contained in:
@@ -16,7 +16,6 @@ VEHICLE_HREF_RE = re.compile(r"/VehicleDetail/\d+(?:~[A-Z]{2})?", re.IGNORECASE)
|
||||
|
||||
@dataclass(slots=True)
|
||||
class ListingVehicleLink:
|
||||
# Ссылка на карточку.
|
||||
href: str
|
||||
title: str = ""
|
||||
lot_number: str | None = None
|
||||
@@ -24,7 +23,6 @@ class ListingVehicleLink:
|
||||
|
||||
@dataclass(slots=True)
|
||||
class ListingPageResult:
|
||||
# Результат страницы листинга.
|
||||
source_url: str
|
||||
page_number: int
|
||||
vehicle_links: list[ListingVehicleLink] = field(default_factory=list)
|
||||
@@ -34,12 +32,10 @@ class ListingPageResult:
|
||||
|
||||
class ListingCollector:
|
||||
def __init__(self, settings: Settings, pacer: HumanPacer) -> None:
|
||||
# Сборщик ссылок листинга.
|
||||
self.settings = settings
|
||||
self.pacer = pacer
|
||||
|
||||
def open_cars_listing(self, page: Page) -> None:
|
||||
# Открываем листинг и ждем ссылки.
|
||||
logger.info("Opening cars listing page: %s", self.settings.listing.cars_url)
|
||||
page.goto(self.settings.listing.cars_url, wait_until="domcontentloaded")
|
||||
try:
|
||||
@@ -53,7 +49,6 @@ class ListingCollector:
|
||||
self.pacer.after_listing_open()
|
||||
|
||||
def apply_filters(self, page: Page, make: str | None = None, model: str | None = None) -> dict[str, str | None]:
|
||||
# Пробуем make/model фильтры.
|
||||
applied = {"make": None, "model": None}
|
||||
if make and self._try_fill_filter_input(page, ["input[placeholder*='Make']", "input[aria-label*='Make']"], make):
|
||||
applied["make"] = make
|
||||
@@ -64,7 +59,6 @@ class ListingCollector:
|
||||
return applied
|
||||
|
||||
def collect_current_page(self, page: Page, page_number: int = 1) -> ListingPageResult:
|
||||
# Собираем ссылки текущей страницы.
|
||||
anchors = page.locator("a[href*='/VehicleDetail/']")
|
||||
total = min(anchors.count(), self.settings.listing.page_link_limit)
|
||||
links: list[ListingVehicleLink] = []
|
||||
@@ -87,7 +81,6 @@ class ListingCollector:
|
||||
return ListingPageResult(source_url=page.url, page_number=page_number, vehicle_links=links, pagination_available=next_page_detected, next_page_detected=next_page_detected)
|
||||
|
||||
def go_to_next_page(self, page: Page) -> bool:
|
||||
# Переход на следующую страницу.
|
||||
selectors = ["a[aria-label*='Next']", "button[aria-label*='Next']", "a.pagination-next", "button.pagination-next", "a:has-text('Next')", "button:has-text('Next')"]
|
||||
for selector in selectors:
|
||||
locator = page.locator(selector).first
|
||||
@@ -109,7 +102,6 @@ class ListingCollector:
|
||||
return False
|
||||
|
||||
def collect_listing_links(self, page: Page, *, make: str | None = None, model: str | None = None) -> dict[str, Any]:
|
||||
# Последовательный сбор с лимитами.
|
||||
self.open_cars_listing(page)
|
||||
applied_filters = self.apply_filters(page, make=make, model=model)
|
||||
pages: list[dict[str, object]] = []
|
||||
@@ -130,7 +122,6 @@ class ListingCollector:
|
||||
|
||||
@staticmethod
|
||||
def _try_fill_filter_input(page: Page, selectors: list[str], value: str) -> bool:
|
||||
# Несколько селекторов для фильтра.
|
||||
for selector in selectors:
|
||||
locator = page.locator(selector).first
|
||||
if locator.count() == 0:
|
||||
@@ -150,7 +141,6 @@ class ListingCollector:
|
||||
|
||||
@staticmethod
|
||||
def _has_next_page(page: Page) -> bool:
|
||||
# Проверка кнопки next.
|
||||
for selector in ["a[aria-label*='Next']", "button[aria-label*='Next']", "a.pagination-next", "button.pagination-next", "a:has-text('Next')", "button:has-text('Next')"]:
|
||||
if page.locator(selector).count() > 0:
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user