DEV Community

agenthustler
agenthustler

Posted on

How to Monitor Brand Reputation Across Review Sites with Python

How to Monitor Brand Reputation Across Review Sites with Python

Your brand's reputation lives on review sites, forums, and social platforms. Manually checking G2, Trustpilot, Capterra, and app stores daily is impractical. Let's automate it.

What We're Building

A Python pipeline that:

  • Scrapes reviews from multiple platforms
  • Performs sentiment analysis
  • Detects sudden rating drops
  • Sends alerts on negative review spikes

Setup

import requests
from bs4 import BeautifulSoup
import json
from datetime import datetime
from collections import defaultdict

PROXY_URL = "https://api.scraperapi.com"
API_KEY = "YOUR_SCRAPERAPI_KEY"
Enter fullscreen mode Exit fullscreen mode

Review sites heavily guard against scraping. ScraperAPI handles their anti-bot defenses so you can focus on the data.

Scraping Trustpilot Reviews

def scrape_trustpilot(company_slug, pages=5):
    reviews = []
    for page in range(1, pages + 1):
        params = {
            "api_key": API_KEY,
            "url": f"https://www.trustpilot.com/review/{company_slug}?page={page}"
        }
        response = requests.get(PROXY_URL, params=params)
        soup = BeautifulSoup(response.text, "html.parser")

        for card in soup.select("[data-review-id]"):
            rating_el = card.select_one("[data-rating]")
            title_el = card.select_one("h2")
            body_el = card.select_one("[data-service-review-text-typography]")
            date_el = card.select_one("time")

            reviews.append({
                "platform": "trustpilot",
                "rating": int(rating_el["data-rating"]) if rating_el else None,
                "title": title_el.text.strip() if title_el else "",
                "body": body_el.text.strip() if body_el else "",
                "date": date_el.get("datetime", "") if date_el else "",
                "scraped_at": datetime.now().isoformat()
            })
        import time; time.sleep(3)
    return reviews
Enter fullscreen mode Exit fullscreen mode

Scraping G2 Reviews

def scrape_g2(product_slug, pages=3):
    reviews = []
    for page in range(1, pages + 1):
        params = {
            "api_key": API_KEY,
            "url": f"https://www.g2.com/products/{product_slug}/reviews?page={page}",
            "render": "true"
        }
        response = requests.get(PROXY_URL, params=params)
        soup = BeautifulSoup(response.text, "html.parser")

        for review in soup.select(".review-listing"):
            stars = review.select_one(".stars")
            title = review.select_one(".review-title")
            body = review.select_one(".review-body")

            star_count = len(stars.select(".filled")) if stars else 0
            reviews.append({
                "platform": "g2",
                "rating": star_count,
                "title": title.text.strip() if title else "",
                "body": body.text.strip()[:500] if body else "",
                "scraped_at": datetime.now().isoformat()
            })
        import time; time.sleep(4)
    return reviews
Enter fullscreen mode Exit fullscreen mode

Sentiment Analysis

from textblob import TextBlob

def analyze_sentiment(reviews):
    for review in reviews:
        blob = TextBlob(review["body"])
        review["sentiment"] = round(blob.sentiment.polarity, 3)
        review["subjectivity"] = round(blob.sentiment.subjectivity, 3)

        if review["sentiment"] < -0.3:
            review["flag"] = "negative"
        elif review["sentiment"] > 0.3:
            review["flag"] = "positive"
        else:
            review["flag"] = "neutral"
    return reviews

def reputation_summary(reviews):
    by_platform = defaultdict(list)
    for r in reviews:
        by_platform[r["platform"]].append(r)

    summary = {}
    for platform, revs in by_platform.items():
        ratings = [r["rating"] for r in revs if r["rating"]]
        sentiments = [r["sentiment"] for r in revs]
        negative = [r for r in revs if r.get("flag") == "negative"]

        summary[platform] = {
            "avg_rating": round(sum(ratings)/len(ratings), 2) if ratings else 0,
            "avg_sentiment": round(sum(sentiments)/len(sentiments), 3) if sentiments else 0,
            "total_reviews": len(revs),
            "negative_count": len(negative),
            "negative_pct": round(len(negative)/len(revs)*100, 1) if revs else 0
        }
    return summary
Enter fullscreen mode Exit fullscreen mode

Alert System

def check_reputation_alerts(current, previous):
    alerts = []

    for platform in current:
        if platform in previous:
            rating_drop = previous[platform]["avg_rating"] - current[platform]["avg_rating"]
            neg_spike = current[platform]["negative_pct"] - previous[platform]["negative_pct"]

            if rating_drop > 0.3:
                alerts.append(f"Rating dropped {rating_drop:.1f} on {platform}")
            if neg_spike > 15:
                alerts.append(f"Negative reviews spiked {neg_spike:.0f}% on {platform}")

    return alerts
Enter fullscreen mode Exit fullscreen mode

Proxy Considerations

Review sites invest heavily in anti-scraping:

  • ScraperAPI — handles Trustpilot and G2's advanced bot detection
  • ThorData — residential IPs that look like real users browsing reviews
  • ScrapeOps — track success rates and catch when sites change their structure

Conclusion

Automated reputation monitoring turns scattered reviews into a real-time health dashboard for your brand. Set it to run daily, alert on anomalies, and you'll never be surprised by a review crisis again.

Top comments (0)