fix dubizzle listing extraction
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user