"""GoDaddy TLD price scraper. GoDaddy is the world's largest domain registrar with significant market share. Their prices are important for market comparison, especially for promotional pricing. """ import logging from datetime import datetime from typing import Optional import httpx from app.services.tld_scraper.base import BaseTLDScraper, TLDPriceData, ScraperError logger = logging.getLogger(__name__) class GoDaddyScraper(BaseTLDScraper): """ Scraper for GoDaddy domain prices. GoDaddy doesn't have a public pricing API, but we maintain known prices for major TLDs based on their public pricing pages. Key characteristics of GoDaddy pricing: - Low promotional first-year prices - Higher renewal prices (important for "renewal trap" detection) - Frequent sales and discounts """ name = "godaddy" base_url = "https://www.godaddy.com" # Known GoDaddy prices (as of Dec 2024) # Note: GoDaddy has aggressive promo pricing but high renewals # Source: https://www.godaddy.com/tlds GODADDY_PRICES = { # Major TLDs - Note the renewal trap on many! "com": {"reg": 11.99, "renew": 22.99, "transfer": 11.99, "promo": 0.99}, "net": {"reg": 14.99, "renew": 23.99, "transfer": 14.99}, "org": {"reg": 9.99, "renew": 23.99, "transfer": 9.99}, "info": {"reg": 2.99, "renew": 24.99, "transfer": 2.99, "promo": True}, "biz": {"reg": 16.99, "renew": 24.99, "transfer": 16.99}, # Premium ccTLDs "io": {"reg": 44.99, "renew": 59.99, "transfer": 44.99}, "co": {"reg": 11.99, "renew": 38.99, "transfer": 11.99}, "ai": {"reg": 79.99, "renew": 99.99, "transfer": 79.99}, "me": {"reg": 2.99, "renew": 19.99, "transfer": 2.99, "promo": True}, # Tech TLDs "dev": {"reg": 15.99, "renew": 19.99, "transfer": 15.99}, "app": {"reg": 17.99, "renew": 21.99, "transfer": 17.99}, "tech": {"reg": 4.99, "renew": 54.99, "transfer": 4.99, "promo": True}, # Major trap! "xyz": {"reg": 0.99, "renew": 14.99, "transfer": 0.99, "promo": True}, # Budget/Promo TLDs (watch out for renewals!) "online": {"reg": 0.99, "renew": 44.99, "transfer": 0.99, "promo": True}, "site": {"reg": 0.99, "renew": 39.99, "transfer": 0.99, "promo": True}, "store": {"reg": 0.99, "renew": 59.99, "transfer": 0.99, "promo": True}, "club": {"reg": 0.99, "renew": 16.99, "transfer": 0.99, "promo": True}, "website": {"reg": 0.99, "renew": 24.99, "transfer": 0.99, "promo": True}, "space": {"reg": 0.99, "renew": 24.99, "transfer": 0.99, "promo": True}, # European ccTLDs "uk": {"reg": 8.99, "renew": 12.99, "transfer": 8.99}, "de": {"reg": 9.99, "renew": 14.99, "transfer": 9.99}, "eu": {"reg": 6.99, "renew": 12.99, "transfer": 6.99}, "fr": {"reg": 11.99, "renew": 14.99, "transfer": 11.99}, "nl": {"reg": 9.99, "renew": 14.99, "transfer": 9.99}, # Other popular TLDs "ca": {"reg": 12.99, "renew": 19.99, "transfer": 12.99}, "us": {"reg": 5.99, "renew": 21.99, "transfer": 5.99}, "tv": {"reg": 34.99, "renew": 44.99, "transfer": 34.99}, "cc": {"reg": 9.99, "renew": 14.99, "transfer": 9.99}, # New gTLDs "shop": {"reg": 2.99, "renew": 39.99, "transfer": 2.99, "promo": True}, "blog": {"reg": 2.99, "renew": 34.99, "transfer": 2.99, "promo": True}, "cloud": {"reg": 4.99, "renew": 24.99, "transfer": 4.99, "promo": True}, "live": {"reg": 2.99, "renew": 29.99, "transfer": 2.99, "promo": True}, "world": {"reg": 2.99, "renew": 34.99, "transfer": 2.99, "promo": True}, } async def scrape(self) -> list[TLDPriceData]: """ Return GoDaddy's known pricing data. Since GoDaddy doesn't expose a public pricing API, we use curated data from their public pricing pages. Returns: List of TLDPriceData objects with GoDaddy pricing """ results = [] now = datetime.utcnow() for tld, prices in self.GODADDY_PRICES.items(): # Determine if this is promotional pricing is_promo = prices.get("promo", False) promo_price = prices["reg"] if is_promo else None results.append(TLDPriceData( tld=tld, registrar="godaddy", registration_price=prices["reg"], renewal_price=prices["renew"], transfer_price=prices.get("transfer"), promo_price=promo_price, currency="USD", source="static", confidence=0.9, # Static data, updated periodically scraped_at=now, notes="High renewal trap alert" if prices["renew"] > prices["reg"] * 3 else None, )) logger.info(f"Loaded {len(results)} GoDaddy prices") return results async def health_check(self) -> bool: """Check if GoDaddy is accessible.""" try: async with httpx.AsyncClient(timeout=10.0) as client: response = await client.get( self.base_url, headers=self.get_headers(), follow_redirects=True, ) return response.status_code == 200 except Exception as e: logger.debug(f"GoDaddy health check failed: {e}") return False