fix: extracao individual de nota de avaliacao (rating) e total de avaliacoes por estabelecimento

This commit is contained in:
2026-08-26 17:55:21 -03:00
parent dfa5315dec
commit 6038a936ec
+58 -21
View File
@@ -12,6 +12,61 @@ logger = logging.getLogger(__name__)
class ScraperService:
@staticmethod
def _extract_rating_and_reviews(detail_panel, text_fallback: str = "") -> tuple:
"""
Extrai a nota de avaliação (ex: 4.8) e o total de avaliações (ex: 150)
específicos de cada estabelecimento no Google Maps.
"""
rating = 0.0
total_avaliacoes = 0
if detail_panel:
# 1. Procurar elemento específico de nota (ex: <span aria-label="4,8 estrelas"> ou <span class="ceYyJf">)
star_elem = detail_panel.query_selector("[aria-label*='estrela'], [aria-label*='star'], span.ceYyJf, div.F7L8d")
if star_elem:
aria_txt = star_elem.get_attribute("aria-label") or star_elem.inner_text()
m = re.search(r'([1-5][.,]\d)', aria_txt)
if m:
try:
rating = float(m.group(1).replace(',', '.'))
except ValueError:
pass
# 2. Procurar elemento específico de total de avaliações (ex: <button aria-label="1.250 avaliações">)
rev_elem = detail_panel.query_selector("button[aria-label*='avaliaç'], span[aria-label*='avaliaç'], [aria-label*='avaliações']")
if rev_elem:
rev_txt = rev_elem.get_attribute("aria-label") or rev_elem.inner_text()
m = re.search(r'([\d.,]+)\s*avaliaç', rev_txt, re.IGNORECASE)
if m:
try:
total_avaliacoes = int(re.sub(r'\D', '', m.group(1)))
except ValueError:
pass
# Fallback usando o texto bruto do painel do lugar
if rating == 0.0 and text_fallback:
m = re.search(r'([1-5][.,]\d)\s*(?:estrelas?|★|\s*\(|\s*·)', text_fallback, re.IGNORECASE)
if not m:
m = re.search(r'([1-5][.,]\d)', text_fallback)
if m:
try:
rating = float(m.group(1).replace(',', '.'))
except ValueError:
pass
if total_avaliacoes == 0 and text_fallback:
m = re.search(r'([\d.,]+)\s*avaliaç', text_fallback, re.IGNORECASE)
if not m:
m = re.search(r'\(([\d.,]+)\)', text_fallback)
if m:
try:
total_avaliacoes = int(re.sub(r'\D', '', m.group(1)))
except ValueError:
pass
return rating, total_avaliacoes
@staticmethod
def scrape_google_maps(search_query: str, max_results: int = 15, headless: bool = True) -> List[Dict[str, Any]]:
"""
@@ -163,17 +218,8 @@ class ScraperService:
if site_btn:
website = site_btn.get_attribute("href") or ""
# 5. Rating e Avaliações
rating = 0.0
total_avaliacoes = 0
rating_match = re.search(r'([1-5][.,]\d)\s*(?:\(([\d.,]+)\))?', detail_text)
if rating_match:
try:
rating = float(rating_match.group(1).replace(',', '.'))
if rating_match.group(2):
total_avaliacoes = int(re.sub(r'\D', '', rating_match.group(2)))
except ValueError:
pass
# 5. Rating e Avaliações reais por estabelecimento
rating, total_avaliacoes = ScraperService._extract_rating_and_reviews(detail_panel, detail_text)
results.append({
'nome_empresa': nome_empresa,
@@ -217,16 +263,7 @@ class ScraperService:
if site_btn:
website = site_btn.get_attribute("href") or ""
rating = 0.0
total_avaliacoes = 0
rating_match = re.search(r'([1-5][.,]\d)\s*(?:\(([\d.,]+)\))?', detail_text)
if rating_match:
try:
rating = float(rating_match.group(1).replace(',', '.'))
if rating_match.group(2):
total_avaliacoes = int(re.sub(r'\D', '', rating_match.group(2)))
except ValueError:
pass
rating, total_avaliacoes = ScraperService._extract_rating_and_reviews(detail_panel, detail_text)
results.append({
'nome_empresa': nome_empresa,