sync
This commit is contained in:
+10
-1
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
import re
|
||||
from collections.abc import Callable
|
||||
from urllib.parse import urlsplit, urlunsplit
|
||||
|
||||
from playwright.sync_api import TimeoutError as PlaywrightTimeoutError
|
||||
@@ -98,8 +99,12 @@ def _open_reviews(page):
|
||||
pass
|
||||
|
||||
|
||||
def get_rating_distribution(url: str) -> dict:
|
||||
def get_rating_distribution(
|
||||
url: str,
|
||||
progress: Callable[[int, str], None] | None = None,
|
||||
) -> dict:
|
||||
"""Pobiera pięć zbiorczych liczników. Treści opinii nie są odczytywane ani zapisywane."""
|
||||
report = progress or (lambda _percent, _message: None)
|
||||
try:
|
||||
with sync_playwright() as playwright:
|
||||
headless = os.environ.get("CHROMIUM_HEADLESS", "1").lower() not in {"0", "false", "no"}
|
||||
@@ -131,13 +136,16 @@ def get_rating_distribution(url: str) -> dict:
|
||||
browser = playwright.chromium.launch(**launch)
|
||||
context = browser.new_context(locale="pl-PL", viewport={"width": 1100, "height": 800})
|
||||
try:
|
||||
report(50, "Otwarto Chromium")
|
||||
page = context.pages[0] if context.pages else context.new_page()
|
||||
context.add_init_script(
|
||||
"Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
|
||||
)
|
||||
page.goto(url, wait_until="domcontentloaded", timeout=30_000)
|
||||
_accept_cookies(page)
|
||||
report(75, "Załadowano Google Maps")
|
||||
_open_reviews(page)
|
||||
report(90, "Otwarto panel opinii")
|
||||
page.wait_for_timeout(700)
|
||||
labels = page.locator("[aria-label]").evaluate_all(
|
||||
"els => els.map(el => el.getAttribute('aria-label')).filter(Boolean)"
|
||||
@@ -148,6 +156,7 @@ def get_rating_distribution(url: str) -> dict:
|
||||
if "ograniczonego widoku" in body_text or "limited view" in body_text:
|
||||
raise ScrapeError("Google włączyło ograniczony widok i ukryło opinie. Spróbuj później lub z innego łącza.")
|
||||
raise ScrapeError("Nie udało się odczytać dokładnych pięciu liczników. Sprawdź link do miejsca.")
|
||||
report(99, "Pojawiły się liczniki")
|
||||
ratings = {str(stars): counts[stars] for stars in range(5, 0, -1)}
|
||||
total = sum(ratings.values())
|
||||
average = round(sum(int(stars) * count for stars, count in ratings.items()) / total, 2) if total else 0
|
||||
|
||||
Reference in New Issue
Block a user