Commit ·
0e9e349
1
Parent(s): 51fe39a
Use Google Trends RSS for Trending Now - more reliable than pytrends API
Browse files
modules/trends/schemas.py
CHANGED
|
@@ -91,6 +91,7 @@ class TrendingTopic(BaseModel):
|
|
| 91 |
rank: int
|
| 92 |
topic: str
|
| 93 |
country: str
|
|
|
|
| 94 |
|
| 95 |
|
| 96 |
class TrendingNowResponse(BaseModel):
|
|
|
|
| 91 |
rank: int
|
| 92 |
topic: str
|
| 93 |
country: str
|
| 94 |
+
traffic: str = "N/A"
|
| 95 |
|
| 96 |
|
| 97 |
class TrendingNowResponse(BaseModel):
|
modules/trends/services/trends_client.py
CHANGED
|
@@ -81,7 +81,8 @@ class TrendsClient:
|
|
| 81 |
limit: int = 20
|
| 82 |
) -> List[Dict]:
|
| 83 |
"""
|
| 84 |
-
Get currently trending searches.
|
|
|
|
| 85 |
|
| 86 |
Args:
|
| 87 |
country: Country code (e.g., 'united_states', 'bangladesh', 'india')
|
|
@@ -90,24 +91,71 @@ class TrendsClient:
|
|
| 90 |
Returns:
|
| 91 |
List of trending topics with rank
|
| 92 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
try:
|
| 94 |
-
#
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
results = []
|
| 98 |
-
|
| 99 |
-
results.append({
|
| 100 |
-
"rank": i + 1,
|
| 101 |
-
"topic": topic,
|
| 102 |
-
"country": country
|
| 103 |
-
})
|
| 104 |
|
| 105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
return results
|
| 107 |
|
| 108 |
except Exception as e:
|
| 109 |
-
logger.error(f"Error getting trending searches: {e}")
|
| 110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
|
| 112 |
def get_realtime_trends(
|
| 113 |
self,
|
|
|
|
| 81 |
limit: int = 20
|
| 82 |
) -> List[Dict]:
|
| 83 |
"""
|
| 84 |
+
Get currently trending searches using Google Trends RSS feed.
|
| 85 |
+
More reliable than pytrends API for daily trends.
|
| 86 |
|
| 87 |
Args:
|
| 88 |
country: Country code (e.g., 'united_states', 'bangladesh', 'india')
|
|
|
|
| 91 |
Returns:
|
| 92 |
List of trending topics with rank
|
| 93 |
"""
|
| 94 |
+
import requests
|
| 95 |
+
import xml.etree.ElementTree as ET
|
| 96 |
+
|
| 97 |
+
# Country code mapping for RSS
|
| 98 |
+
country_codes = {
|
| 99 |
+
"united_states": "US",
|
| 100 |
+
"united_kingdom": "GB",
|
| 101 |
+
"india": "IN",
|
| 102 |
+
"bangladesh": "BD",
|
| 103 |
+
"japan": "JP",
|
| 104 |
+
"germany": "DE",
|
| 105 |
+
"france": "FR",
|
| 106 |
+
"brazil": "BR",
|
| 107 |
+
"canada": "CA",
|
| 108 |
+
"australia": "AU",
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
geo = country_codes.get(country, "US")
|
| 112 |
+
|
| 113 |
try:
|
| 114 |
+
# Google Trends RSS Feed URL
|
| 115 |
+
rss_url = f"https://trends.google.com/trending/rss?geo={geo}"
|
| 116 |
+
|
| 117 |
+
response = requests.get(rss_url, timeout=10)
|
| 118 |
+
response.raise_for_status()
|
| 119 |
+
|
| 120 |
+
# Parse XML
|
| 121 |
+
root = ET.fromstring(response.content)
|
| 122 |
|
| 123 |
results = []
|
| 124 |
+
items = root.findall('.//item')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
|
| 126 |
+
for i, item in enumerate(items[:limit]):
|
| 127 |
+
title = item.find('title')
|
| 128 |
+
traffic = item.find('{https://trends.google.com/trending/rss}approx_traffic')
|
| 129 |
+
|
| 130 |
+
if title is not None:
|
| 131 |
+
results.append({
|
| 132 |
+
"rank": i + 1,
|
| 133 |
+
"topic": title.text,
|
| 134 |
+
"country": country,
|
| 135 |
+
"traffic": traffic.text if traffic is not None else "N/A"
|
| 136 |
+
})
|
| 137 |
+
|
| 138 |
+
logger.info(f"Got {len(results)} trending topics for {country} via RSS")
|
| 139 |
return results
|
| 140 |
|
| 141 |
except Exception as e:
|
| 142 |
+
logger.error(f"Error getting trending searches via RSS: {e}")
|
| 143 |
+
# Fallback to pytrends
|
| 144 |
+
try:
|
| 145 |
+
df = self.pytrends.trending_searches(pn=country)
|
| 146 |
+
results = []
|
| 147 |
+
for i, topic in enumerate(df[0].head(limit).tolist()):
|
| 148 |
+
results.append({
|
| 149 |
+
"rank": i + 1,
|
| 150 |
+
"topic": topic,
|
| 151 |
+
"country": country,
|
| 152 |
+
"traffic": "N/A"
|
| 153 |
+
})
|
| 154 |
+
logger.info(f"Got {len(results)} trending topics via pytrends fallback")
|
| 155 |
+
return results
|
| 156 |
+
except Exception as e2:
|
| 157 |
+
logger.error(f"Fallback also failed: {e2}")
|
| 158 |
+
return []
|
| 159 |
|
| 160 |
def get_realtime_trends(
|
| 161 |
self,
|