fix dubizzle listing extraction

This commit is contained in:
qananasikq
2026-05-08 13:31:22 +03:00
parent 42bd4c64d6
commit 046e9f125f
2 changed files with 281 additions and 5 deletions

View File

@@ -8,6 +8,11 @@ from ..core.utils import LOT_RE, PRICE_RE, deep_find_all_keys, deep_find_key, fi
logger = logging.getLogger("dubizzle_scraper.parsers")
NEXT_DATA_RE = re.compile(
r'<script[^>]+id=["\']__NEXT_DATA__["\'][^>]*type=["\']application/json["\'][^>]*>(.*?)</script>',
re.IGNORECASE | re.DOTALL,
)
class VehicleParser:
# Парсер страницы авто.
@@ -157,6 +162,11 @@ class VehicleParser:
network_dump = network_dump or {}
responses = network_dump.get("json_responses", [])
payloads = [item.get("payload") for item in responses if isinstance(item.get("payload"), (dict, list))]
embedded = self._extract_embedded_json(page_html)
for item in embedded:
payload = item.get("payload")
if isinstance(payload, (dict, list)):
payloads.append(payload)
dom_kv = self._parse_dom_key_value_pairs(dom_text)
page_title = ""
title_match = re.search(r"<title[^>]*>(.*?)</title>", page_html or "", re.IGNORECASE | re.DOTALL)
@@ -194,11 +204,9 @@ class VehicleParser:
if not summary.get("current_bid") and len(prices) > 1:
summary["current_bid"] = prices[1]
embedded = self._extract_embedded_json(page_html)
for item in embedded:
p = item.get("payload")
if isinstance(p, (dict, list)):
payloads.append(p)
# Доп. проход по JSON.
extra = deep_find_all_keys([p], self.SUMMARY_KEY_MAP)
for field, vals in extra.items():
@@ -299,6 +307,11 @@ class VehicleParser:
@staticmethod
def _guess_currency(summary: dict[str, Any]) -> str:
for key in ["currency", "price", "buy_now", "current_bid", "actual_cash_value", "estimated_repair_cost"]:
value = str(summary.get(key) or "")
upper = value.upper()
if "AED" in upper or "د.إ" in value:
return "AED"
for key in ["buy_now", "current_bid", "actual_cash_value", "estimated_repair_cost"]:
value = str(summary.get(key) or "")
if "$" in value:
@@ -322,9 +335,18 @@ class VehicleParser:
def _extract_embedded_json(html: str) -> list[dict[str, Any]]:
scripts = re.findall(r"<script[^>]*>(.*?)</script>", html or "", flags=re.DOTALL | re.IGNORECASE)
extracted: list[dict[str, Any]] = []
next_match = NEXT_DATA_RE.search(html or "")
if next_match:
try:
next_data = json.loads(html_module.unescape(next_match.group(1).strip()))
extracted.append({"type": "next_data", "payload": next_data})
except Exception:
pass
for script_text in scripts:
if "{" not in script_text and "[" not in script_text:
continue
if "__NEXT_DATA__" in script_text:
continue
# Пропускаем большие блоки.
if len(script_text) > 51_200:
continue