11from typing import Any , Literal
2- import os
32from dataclasses import dataclass , field
43from collections import defaultdict
54from human_requests import HumanBrowser , HumanContext , HumanPage
98 WaitHeader ,
109 WaitSource ,
1110)
12- from camoufox import AsyncCamoufox
13- from playwright .async_api import TimeoutError as PWTimeoutError
11+ from camoufox import AsyncCamoufox , DefaultAddons
1412
1513from human_requests import ApiParent , api_child_field
1614from .endpoints .catalog import ClassCatalog
@@ -27,6 +25,8 @@ class FixPriceAPI(ApiParent):
2725 """Время ожидания ответа от сервера в миллисекундах."""
2826 headless : bool = True
2927 """Запускать браузер в headless режиме?"""
28+ test_mode : bool = False
29+ """Режим тестирования предполагает более глубокий _warmup который не требуется для обычного использования"""
3030 proxy : str | dict | Proxy | None = field (default_factory = Proxy .from_env )
3131 """Прокси-сервер для всех запросов (если нужен). По умолчанию берет из окружения (если есть).
3232 Принимает как формат Playwright, так и строчный формат."""
@@ -48,6 +48,8 @@ class FixPriceAPI(ApiParent):
4848
4949 unstandard_headers : dict [str , str ] = field (init = False , repr = False )
5050 """Список нестандартных заголовков пойманных при инициализации"""
51+ unstandard_urls : dict [str , list [str ]] = field (init = False , repr = False )
52+ """Список нестандартных заголовков пойманных при инициализации"""
5153
5254 Geolocation : ClassGeolocation = api_child_field (ClassGeolocation )
5355 """API для работы с геолокацией."""
@@ -70,8 +72,11 @@ async def _warmup(self) -> None:
7072 br = await AsyncCamoufox (
7173 headless = self .headless ,
7274 proxy = px .as_dict (),
75+ humanize = True ,
7376 ** self .browser_opts ,
7477 block_images = True ,
78+ i_know_what_im_doing = True ,
79+ exclude_addons = [DefaultAddons .UBO ]
7580 ).start ()
7681
7782 self .session = HumanBrowser .replace (br )
@@ -97,6 +102,17 @@ async def _warmup(self) -> None:
97102 timeout_ms = self .timeout_ms ,
98103 )
99104
105+ if self .test_mode :
106+ btn = self .page .locator ("div.selected-city > div.buttons > button.button.normal" ).first
107+ await btn .wait_for (state = "visible" , timeout = self .timeout_ms )
108+ await btn .click (timeout = self .timeout_ms )
109+
110+ await self .page .locator ("a.link.product-category" ).first .click ()
111+ await self .page .wait_for_selector (
112+ selector = "div.page-content" , timeout = self .timeout_ms , state = "visible"
113+ )
114+ await self .page .wait_for_load_state ("load" )
115+
100116 await self .page .goto (
101117 self .CATALOG_URL , wait_until = "networkidle"
102118 ) # ускорение сети, таким образом пропускаем OPTION pre-fetch
@@ -116,6 +132,7 @@ async def _warmup(self) -> None:
116132
117133 # Преобразуем set обратно в list
118134 self .unstandard_headers = {k : list (v )[0 ] for k , v in result .items ()}
135+ self .unstandard_urls = result_sniffer ["request" ]
119136
120137 async def __aexit__ (self , * exc ):
121138 """Выход из контекстного менеджера с закрытием сессии."""
0 commit comments