pytrends-modern 0.1.1__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pytrends_modern-0.1.1/pytrends_modern.egg-info → pytrends_modern-0.2.0}/PKG-INFO +111 -2
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/README.md +106 -0
- pytrends_modern-0.2.0/examples/example_browser_mode.py +92 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/pyproject.toml +11 -2
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/pytrends_modern/__init__.py +7 -1
- pytrends_modern-0.2.0/pytrends_modern/browser_config.py +94 -0
- pytrends_modern-0.2.0/pytrends_modern/browser_config_camoufox.py +67 -0
- pytrends_modern-0.2.0/pytrends_modern/camoufox_setup.py +300 -0
- pytrends_modern-0.2.0/pytrends_modern/proxy_extension.py +78 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/pytrends_modern/request.py +455 -10
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/pytrends_modern/rss.py +8 -8
- pytrends_modern-0.2.0/pytrends_modern/scraper.py +292 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0/pytrends_modern.egg-info}/PKG-INFO +111 -2
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/pytrends_modern.egg-info/SOURCES.txt +6 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/pytrends_modern.egg-info/requires.txt +4 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/LICENSE +0 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/MANIFEST.in +0 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/examples/advanced_usage.py +0 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/examples/basic_usage.py +0 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/pytrends_modern/cli.py +0 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/pytrends_modern/config.py +0 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/pytrends_modern/exceptions.py +0 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/pytrends_modern/py.typed +0 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/pytrends_modern/utils.py +0 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/pytrends_modern.egg-info/dependency_links.txt +0 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/pytrends_modern.egg-info/entry_points.txt +0 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/pytrends_modern.egg-info/top_level.txt +0 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/setup.cfg +0 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/tests/conftest.py +0 -0
- {pytrends_modern-0.1.1 → pytrends_modern-0.2.0}/tests/test_basic.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pytrends-modern
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: Modern Google Trends API - Combining the best of pytrends, with RSS feeds, Selenium scraping, and enhanced features
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Modern Google Trends API - Combining the best of pytrends, with RSS feeds, Selenium scraping, DrissionPage browser automation, and enhanced features
|
|
5
5
|
Author: pytrends-modern contributors
|
|
6
6
|
License: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/yiromo/pytrends-modern
|
|
@@ -28,6 +28,9 @@ Requires-Dist: lxml>=4.9.0
|
|
|
28
28
|
Provides-Extra: selenium
|
|
29
29
|
Requires-Dist: selenium>=4.0.0; extra == "selenium"
|
|
30
30
|
Requires-Dist: webdriver-manager>=4.0.0; extra == "selenium"
|
|
31
|
+
Provides-Extra: browser
|
|
32
|
+
Requires-Dist: camoufox[geoip]>=0.4.11; extra == "browser"
|
|
33
|
+
Requires-Dist: browserforge[all]>=1.0.0; extra == "browser"
|
|
31
34
|
Provides-Extra: cli
|
|
32
35
|
Requires-Dist: click>=8.0.0; extra == "cli"
|
|
33
36
|
Requires-Dist: rich>=13.0.0; extra == "cli"
|
|
@@ -74,6 +77,9 @@ pytrends-modern is a **next-generation** Google Trends library that combines:
|
|
|
74
77
|
# Basic installation
|
|
75
78
|
pip install pytrends-modern
|
|
76
79
|
|
|
80
|
+
# With browser mode (Camoufox for bypassing rate limits)
|
|
81
|
+
pip install pytrends-modern[browser]
|
|
82
|
+
|
|
77
83
|
# With Selenium support (for advanced scraping)
|
|
78
84
|
pip install pytrends-modern[selenium]
|
|
79
85
|
|
|
@@ -112,6 +118,71 @@ related = pytrends.related_queries()
|
|
|
112
118
|
print(related['Python']['top'])
|
|
113
119
|
```
|
|
114
120
|
|
|
121
|
+
### 🦊 Browser Mode (Camoufox) - Bypass Rate Limits
|
|
122
|
+
|
|
123
|
+
**NEW!** Use Camoufox with advanced fingerprinting to bypass Google's rate limits by using your Google account:
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
from pytrends_modern import TrendReq, BrowserConfig
|
|
127
|
+
from pytrends_modern.camoufox_setup import setup_profile
|
|
128
|
+
|
|
129
|
+
# First-time setup: Configure Google account login
|
|
130
|
+
setup_profile() # Opens browser - log in to Google once
|
|
131
|
+
|
|
132
|
+
# Use browser mode (persistent login, no rate limits!)
|
|
133
|
+
config = BrowserConfig(headless=False)
|
|
134
|
+
pytrends = TrendReq(browser_config=config)
|
|
135
|
+
|
|
136
|
+
# Works like normal API
|
|
137
|
+
pytrends.kw_list = ['Python']
|
|
138
|
+
df = pytrends.interest_over_time()
|
|
139
|
+
print(df.head())
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Browser Mode Limitations:**
|
|
143
|
+
- ⚠️ Only 1 keyword at a time (no comparisons)
|
|
144
|
+
- ⚠️ Only 'today 1-m' timeframe
|
|
145
|
+
- ⚠️ Only WORLDWIDE region
|
|
146
|
+
- ✅ No rate limits (uses your Google account)
|
|
147
|
+
- ✅ Perfect anti-detection with Camoufox fingerprinting
|
|
148
|
+
|
|
149
|
+
**Setup from command line:**
|
|
150
|
+
```bash
|
|
151
|
+
# Check profile status
|
|
152
|
+
python -m pytrends_modern.camoufox_setup status
|
|
153
|
+
|
|
154
|
+
# Run setup (opens browser for Google login)
|
|
155
|
+
python -m pytrends_modern.camoufox_setup
|
|
156
|
+
|
|
157
|
+
# Export profile for Docker/other machines
|
|
158
|
+
python -m pytrends_modern.camoufox_setup export camoufox-profile.tar.gz
|
|
159
|
+
|
|
160
|
+
# Import profile on another machine
|
|
161
|
+
python -m pytrends_modern.camoufox_setup import camoufox-profile.tar.gz
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Docker Usage:**
|
|
165
|
+
|
|
166
|
+
Yes! You can export your profile and use it in Docker containers:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
# 1. Export profile locally
|
|
170
|
+
python -m pytrends_modern.camoufox_setup export profile.tar.gz
|
|
171
|
+
|
|
172
|
+
# 2. Use in Dockerfile
|
|
173
|
+
COPY profile.tar.gz /tmp/
|
|
174
|
+
RUN mkdir -p /root/.config && \
|
|
175
|
+
cd /root/.config && \
|
|
176
|
+
tar -xzf /tmp/profile.tar.gz
|
|
177
|
+
|
|
178
|
+
# 3. Use headless mode in container
|
|
179
|
+
config = BrowserConfig(headless=True)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
See `Dockerfile.example` for complete Docker setup.
|
|
183
|
+
|
|
184
|
+
⚠️ **Security**: Profile contains Google session - keep secure, don't commit to git!
|
|
185
|
+
|
|
115
186
|
### RSS Feed (Fast Real-Time Data)
|
|
116
187
|
|
|
117
188
|
```python
|
|
@@ -389,6 +460,44 @@ This project builds upon and combines features from:
|
|
|
389
460
|
- CLI interface
|
|
390
461
|
- Multiple export formats
|
|
391
462
|
|
|
463
|
+
## 📌 Important Notes
|
|
464
|
+
|
|
465
|
+
### Google API Changes
|
|
466
|
+
|
|
467
|
+
Google has deprecated several trending search API endpoints. **pytrends-modern provides two working alternatives:**
|
|
468
|
+
|
|
469
|
+
#### Option 1: Fast RSS Feed (Recommended for most use cases)
|
|
470
|
+
```python
|
|
471
|
+
from pytrends_modern import TrendsRSS
|
|
472
|
+
|
|
473
|
+
rss = TrendsRSS()
|
|
474
|
+
trends = rss.get_trends(geo='US') # ~0.7s, returns 10 trends with images/articles
|
|
475
|
+
```
|
|
476
|
+
**Pros:** Lightning fast, includes rich media, no browser needed
|
|
477
|
+
**Cons:** Limited to 10 trends, no filtering options
|
|
478
|
+
|
|
479
|
+
#### Option 2: Selenium Web Scraper (For complete data)
|
|
480
|
+
```python
|
|
481
|
+
from pytrends_modern import TrendsScraper
|
|
482
|
+
|
|
483
|
+
scraper = TrendsScraper(headless=True)
|
|
484
|
+
df = scraper.trending_searches(geo='US', hours=24) # ~15s, returns 400+ trends
|
|
485
|
+
scraper.close()
|
|
486
|
+
```
|
|
487
|
+
**Pros:** Complete data (400+ trends), supports categories/filters
|
|
488
|
+
**Cons:** Slower, requires Chrome browser
|
|
489
|
+
|
|
490
|
+
### Working Features
|
|
491
|
+
✅ All core API methods work perfectly:
|
|
492
|
+
- `interest_over_time()` - Historical search trends
|
|
493
|
+
- `interest_by_region()` - Geographic distribution
|
|
494
|
+
- `related_queries()` / `related_topics()` - Related searches
|
|
495
|
+
- `suggestions()` - Keyword suggestions
|
|
496
|
+
- And more!
|
|
497
|
+
|
|
498
|
+
✅ RSS feeds for 125+ countries
|
|
499
|
+
✅ Selenium scraper for comprehensive trending data
|
|
500
|
+
|
|
392
501
|
## ⚠️ Disclaimer
|
|
393
502
|
|
|
394
503
|
This is an unofficial library and is not affiliated with or endorsed by Google. Use responsibly and in accordance with Google's Terms of Service.
|
|
@@ -27,6 +27,9 @@ pytrends-modern is a **next-generation** Google Trends library that combines:
|
|
|
27
27
|
# Basic installation
|
|
28
28
|
pip install pytrends-modern
|
|
29
29
|
|
|
30
|
+
# With browser mode (Camoufox for bypassing rate limits)
|
|
31
|
+
pip install pytrends-modern[browser]
|
|
32
|
+
|
|
30
33
|
# With Selenium support (for advanced scraping)
|
|
31
34
|
pip install pytrends-modern[selenium]
|
|
32
35
|
|
|
@@ -65,6 +68,71 @@ related = pytrends.related_queries()
|
|
|
65
68
|
print(related['Python']['top'])
|
|
66
69
|
```
|
|
67
70
|
|
|
71
|
+
### 🦊 Browser Mode (Camoufox) - Bypass Rate Limits
|
|
72
|
+
|
|
73
|
+
**NEW!** Use Camoufox with advanced fingerprinting to bypass Google's rate limits by using your Google account:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from pytrends_modern import TrendReq, BrowserConfig
|
|
77
|
+
from pytrends_modern.camoufox_setup import setup_profile
|
|
78
|
+
|
|
79
|
+
# First-time setup: Configure Google account login
|
|
80
|
+
setup_profile() # Opens browser - log in to Google once
|
|
81
|
+
|
|
82
|
+
# Use browser mode (persistent login, no rate limits!)
|
|
83
|
+
config = BrowserConfig(headless=False)
|
|
84
|
+
pytrends = TrendReq(browser_config=config)
|
|
85
|
+
|
|
86
|
+
# Works like normal API
|
|
87
|
+
pytrends.kw_list = ['Python']
|
|
88
|
+
df = pytrends.interest_over_time()
|
|
89
|
+
print(df.head())
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Browser Mode Limitations:**
|
|
93
|
+
- ⚠️ Only 1 keyword at a time (no comparisons)
|
|
94
|
+
- ⚠️ Only 'today 1-m' timeframe
|
|
95
|
+
- ⚠️ Only WORLDWIDE region
|
|
96
|
+
- ✅ No rate limits (uses your Google account)
|
|
97
|
+
- ✅ Perfect anti-detection with Camoufox fingerprinting
|
|
98
|
+
|
|
99
|
+
**Setup from command line:**
|
|
100
|
+
```bash
|
|
101
|
+
# Check profile status
|
|
102
|
+
python -m pytrends_modern.camoufox_setup status
|
|
103
|
+
|
|
104
|
+
# Run setup (opens browser for Google login)
|
|
105
|
+
python -m pytrends_modern.camoufox_setup
|
|
106
|
+
|
|
107
|
+
# Export profile for Docker/other machines
|
|
108
|
+
python -m pytrends_modern.camoufox_setup export camoufox-profile.tar.gz
|
|
109
|
+
|
|
110
|
+
# Import profile on another machine
|
|
111
|
+
python -m pytrends_modern.camoufox_setup import camoufox-profile.tar.gz
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Docker Usage:**
|
|
115
|
+
|
|
116
|
+
Yes! You can export your profile and use it in Docker containers:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# 1. Export profile locally
|
|
120
|
+
python -m pytrends_modern.camoufox_setup export profile.tar.gz
|
|
121
|
+
|
|
122
|
+
# 2. Use in Dockerfile
|
|
123
|
+
COPY profile.tar.gz /tmp/
|
|
124
|
+
RUN mkdir -p /root/.config && \
|
|
125
|
+
cd /root/.config && \
|
|
126
|
+
tar -xzf /tmp/profile.tar.gz
|
|
127
|
+
|
|
128
|
+
# 3. Use headless mode in container
|
|
129
|
+
config = BrowserConfig(headless=True)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
See `Dockerfile.example` for complete Docker setup.
|
|
133
|
+
|
|
134
|
+
⚠️ **Security**: Profile contains Google session - keep secure, don't commit to git!
|
|
135
|
+
|
|
68
136
|
### RSS Feed (Fast Real-Time Data)
|
|
69
137
|
|
|
70
138
|
```python
|
|
@@ -342,6 +410,44 @@ This project builds upon and combines features from:
|
|
|
342
410
|
- CLI interface
|
|
343
411
|
- Multiple export formats
|
|
344
412
|
|
|
413
|
+
## 📌 Important Notes
|
|
414
|
+
|
|
415
|
+
### Google API Changes
|
|
416
|
+
|
|
417
|
+
Google has deprecated several trending search API endpoints. **pytrends-modern provides two working alternatives:**
|
|
418
|
+
|
|
419
|
+
#### Option 1: Fast RSS Feed (Recommended for most use cases)
|
|
420
|
+
```python
|
|
421
|
+
from pytrends_modern import TrendsRSS
|
|
422
|
+
|
|
423
|
+
rss = TrendsRSS()
|
|
424
|
+
trends = rss.get_trends(geo='US') # ~0.7s, returns 10 trends with images/articles
|
|
425
|
+
```
|
|
426
|
+
**Pros:** Lightning fast, includes rich media, no browser needed
|
|
427
|
+
**Cons:** Limited to 10 trends, no filtering options
|
|
428
|
+
|
|
429
|
+
#### Option 2: Selenium Web Scraper (For complete data)
|
|
430
|
+
```python
|
|
431
|
+
from pytrends_modern import TrendsScraper
|
|
432
|
+
|
|
433
|
+
scraper = TrendsScraper(headless=True)
|
|
434
|
+
df = scraper.trending_searches(geo='US', hours=24) # ~15s, returns 400+ trends
|
|
435
|
+
scraper.close()
|
|
436
|
+
```
|
|
437
|
+
**Pros:** Complete data (400+ trends), supports categories/filters
|
|
438
|
+
**Cons:** Slower, requires Chrome browser
|
|
439
|
+
|
|
440
|
+
### Working Features
|
|
441
|
+
✅ All core API methods work perfectly:
|
|
442
|
+
- `interest_over_time()` - Historical search trends
|
|
443
|
+
- `interest_by_region()` - Geographic distribution
|
|
444
|
+
- `related_queries()` / `related_topics()` - Related searches
|
|
445
|
+
- `suggestions()` - Keyword suggestions
|
|
446
|
+
- And more!
|
|
447
|
+
|
|
448
|
+
✅ RSS feeds for 125+ countries
|
|
449
|
+
✅ Selenium scraper for comprehensive trending data
|
|
450
|
+
|
|
345
451
|
## ⚠️ Disclaimer
|
|
346
452
|
|
|
347
453
|
This is an unofficial library and is not affiliated with or endorsed by Google. Use responsibly and in accordance with Google's Terms of Service.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Example: Using pytrends-modern with Camoufox browser mode
|
|
4
|
+
|
|
5
|
+
This example shows how to bypass Google's rate limits by using
|
|
6
|
+
your Google account with Camoufox's advanced fingerprinting.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
# Step 1: First-time setup (only need to do this once)
|
|
10
|
+
print("=" * 70)
|
|
11
|
+
print("STEP 1: Check if profile is configured")
|
|
12
|
+
print("=" * 70)
|
|
13
|
+
|
|
14
|
+
from pytrends_modern.camoufox_setup import is_profile_configured, setup_profile
|
|
15
|
+
|
|
16
|
+
if not is_profile_configured():
|
|
17
|
+
print("\n⚠️ Profile not configured. Running setup...")
|
|
18
|
+
print("This will open a browser for you to log in to Google.")
|
|
19
|
+
print()
|
|
20
|
+
|
|
21
|
+
# Run setup - browser will open
|
|
22
|
+
setup_profile()
|
|
23
|
+
else:
|
|
24
|
+
print("\n✅ Profile already configured!")
|
|
25
|
+
print("Your Google login is saved and ready to use.\n")
|
|
26
|
+
|
|
27
|
+
# Step 2: Use browser mode
|
|
28
|
+
print("=" * 70)
|
|
29
|
+
print("STEP 2: Use browser mode with your Google account")
|
|
30
|
+
print("=" * 70)
|
|
31
|
+
|
|
32
|
+
from pytrends_modern import TrendReq, BrowserConfig
|
|
33
|
+
|
|
34
|
+
# Create browser configuration
|
|
35
|
+
config = BrowserConfig(
|
|
36
|
+
headless=False, # Set to True for headless mode
|
|
37
|
+
humanize=True, # Human-like cursor movements
|
|
38
|
+
os='linux', # or 'windows', 'macos'
|
|
39
|
+
geoip=True # Auto-detect location from IP
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Initialize with browser mode
|
|
43
|
+
pytrends = TrendReq(browser_config=config)
|
|
44
|
+
|
|
45
|
+
# Test with a keyword
|
|
46
|
+
keyword = "Artificial Intelligence"
|
|
47
|
+
print(f"\n🔍 Fetching data for: {keyword}")
|
|
48
|
+
print("⏳ Browser will open briefly...")
|
|
49
|
+
|
|
50
|
+
# Set keyword (browser mode only supports 1 keyword)
|
|
51
|
+
pytrends.kw_list = [keyword]
|
|
52
|
+
|
|
53
|
+
# Get interest over time
|
|
54
|
+
print("\n📊 Interest Over Time:")
|
|
55
|
+
df_time = pytrends.interest_over_time()
|
|
56
|
+
print(df_time.head(10))
|
|
57
|
+
print(f"Total: {len(df_time)} data points")
|
|
58
|
+
|
|
59
|
+
# Get interest by region
|
|
60
|
+
print("\n🌍 Interest By Region (Top 10):")
|
|
61
|
+
df_region = pytrends.interest_by_region()
|
|
62
|
+
df_region_sorted = df_region.sort_values(by=keyword, ascending=False).head(10)
|
|
63
|
+
print(df_region_sorted)
|
|
64
|
+
|
|
65
|
+
# Get related topics
|
|
66
|
+
print("\n🔗 Related Topics:")
|
|
67
|
+
topics = pytrends.related_topics()
|
|
68
|
+
if keyword in topics and topics[keyword].get('top') is not None:
|
|
69
|
+
print(topics[keyword]['top'].head(10))
|
|
70
|
+
else:
|
|
71
|
+
print("No related topics available")
|
|
72
|
+
|
|
73
|
+
# Get related queries
|
|
74
|
+
print("\n❓ Related Queries:")
|
|
75
|
+
queries = pytrends.related_queries()
|
|
76
|
+
if keyword in queries and queries[keyword].get('top') is not None:
|
|
77
|
+
print(queries[keyword]['top'].head(10))
|
|
78
|
+
else:
|
|
79
|
+
print("No related queries available")
|
|
80
|
+
|
|
81
|
+
print("\n" + "=" * 70)
|
|
82
|
+
print("✅ Example complete!")
|
|
83
|
+
print("=" * 70)
|
|
84
|
+
print("\n💡 Tips:")
|
|
85
|
+
print(" - Your Google login is saved in ~/.config/camoufox-pytrends-profile")
|
|
86
|
+
print(" - You only need to log in once")
|
|
87
|
+
print(" - Browser mode has NO rate limits!")
|
|
88
|
+
print(" - Camoufox's fingerprinting bypasses bot detection")
|
|
89
|
+
print("\n⚠️ Limitations:")
|
|
90
|
+
print(" - Only 1 keyword (no comparisons)")
|
|
91
|
+
print(" - Only 'today 1-m' timeframe")
|
|
92
|
+
print(" - Only WORLDWIDE region")
|
|
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pytrends-modern"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "Modern Google Trends API - Combining the best of pytrends, with RSS feeds, Selenium scraping, and enhanced features"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "Modern Google Trends API - Combining the best of pytrends, with RSS feeds, Selenium scraping, DrissionPage browser automation, and enhanced features"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
11
11
|
license = {text = "MIT"}
|
|
@@ -37,6 +37,10 @@ selenium = [
|
|
|
37
37
|
"selenium>=4.0.0",
|
|
38
38
|
"webdriver-manager>=4.0.0",
|
|
39
39
|
]
|
|
40
|
+
browser = [
|
|
41
|
+
"camoufox[geoip]>=0.4.11",
|
|
42
|
+
"browserforge[all]>=1.0.0",
|
|
43
|
+
]
|
|
40
44
|
cli = [
|
|
41
45
|
"click>=8.0.0",
|
|
42
46
|
"rich>=13.0.0",
|
|
@@ -92,3 +96,8 @@ python_files = ["test_*.py"]
|
|
|
92
96
|
python_classes = ["Test*"]
|
|
93
97
|
python_functions = ["test_*"]
|
|
94
98
|
addopts = "-v --cov=pytrends_modern --cov-report=term-missing"
|
|
99
|
+
|
|
100
|
+
[tool.uv.workspace]
|
|
101
|
+
members = [
|
|
102
|
+
"test_space",
|
|
103
|
+
]
|
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
pytrends-modern: Modern Google Trends API
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
__version__ = "
|
|
5
|
+
__version__ = "0.2.0"
|
|
6
6
|
__author__ = "pytrends-modern contributors"
|
|
7
7
|
__license__ = "MIT"
|
|
8
8
|
|
|
9
9
|
from pytrends_modern.request import TrendReq
|
|
10
10
|
from pytrends_modern.rss import TrendsRSS
|
|
11
|
+
from pytrends_modern.scraper import TrendsScraper
|
|
12
|
+
from pytrends_modern.browser_config_camoufox import BrowserConfig
|
|
13
|
+
from pytrends_modern import camoufox_setup
|
|
11
14
|
from pytrends_modern.exceptions import (
|
|
12
15
|
TooManyRequestsError,
|
|
13
16
|
ResponseError,
|
|
@@ -19,6 +22,9 @@ from pytrends_modern.exceptions import (
|
|
|
19
22
|
__all__ = [
|
|
20
23
|
"TrendReq",
|
|
21
24
|
"TrendsRSS",
|
|
25
|
+
"TrendsScraper",
|
|
26
|
+
"BrowserConfig",
|
|
27
|
+
"camoufox_setup",
|
|
22
28
|
"TooManyRequestsError",
|
|
23
29
|
"ResponseError",
|
|
24
30
|
"InvalidParameterError",
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""Browser configuration for DrissionPage automation."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BrowserConfig:
|
|
7
|
+
"""Configuration for DrissionPage browser automation.
|
|
8
|
+
|
|
9
|
+
When enabled, TrendReq will use DrissionPage to capture network traffic
|
|
10
|
+
from trends.google.com instead of making direct API calls.
|
|
11
|
+
|
|
12
|
+
⚠️ LIMITATIONS when using BrowserConfig:
|
|
13
|
+
- Only 1 keyword supported (no comparison)
|
|
14
|
+
- Only 'today 1-m' timeframe supported
|
|
15
|
+
- Only WORLDWIDE geo supported (no geo filtering)
|
|
16
|
+
- Requires Chrome/Chromium browser installed
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
browser_path: Path to Chrome/Chromium executable.
|
|
20
|
+
Defaults: '/usr/bin/chromium' or '/usr/bin/chrome'
|
|
21
|
+
port: Browser remote debugging port (default: 9222)
|
|
22
|
+
headless: Run browser in headless mode (default: True)
|
|
23
|
+
proxy: Proxy server URL (e.g., 'http://proxy.com:8080')
|
|
24
|
+
proxy_username: Proxy username (for authenticated proxies)
|
|
25
|
+
proxy_password: Proxy password (for authenticated proxies)
|
|
26
|
+
user_data_dir: Browser profile directory to persist login session.
|
|
27
|
+
If not provided, creates temp directory (won't persist)
|
|
28
|
+
|
|
29
|
+
Example:
|
|
30
|
+
>>> from pytrends_modern import TrendReq, BrowserConfig
|
|
31
|
+
>>> # Without auth - manual login required once
|
|
32
|
+
>>> config = BrowserConfig(
|
|
33
|
+
... browser_path='/usr/bin/chromium',
|
|
34
|
+
... user_data_dir='~/.config/chromium-pytrends'
|
|
35
|
+
... )
|
|
36
|
+
>>> # With proxy auth
|
|
37
|
+
>>> config = BrowserConfig(
|
|
38
|
+
... browser_path='/usr/bin/chromium',
|
|
39
|
+
... proxy='153.80.44.3:64804',
|
|
40
|
+
... proxy_username='user',
|
|
41
|
+
... proxy_password='pass',
|
|
42
|
+
... user_data_dir='~/.config/chromium-pytrends'
|
|
43
|
+
... )
|
|
44
|
+
>>> pytrends = TrendReq(browser_config=config)
|
|
45
|
+
>>> pytrends.build_payload(['Python']) # Only 1 keyword!
|
|
46
|
+
>>> df = pytrends.interest_over_time()
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
browser_path: Optional[str] = None,
|
|
52
|
+
port: int = 9222,
|
|
53
|
+
headless: bool = True,
|
|
54
|
+
proxy: Optional[str] = None,
|
|
55
|
+
proxy_username: Optional[str] = None,
|
|
56
|
+
proxy_password: Optional[str] = None,
|
|
57
|
+
user_data_dir: Optional[str] = None
|
|
58
|
+
):
|
|
59
|
+
self.browser_path = browser_path or self._get_default_browser_path()
|
|
60
|
+
self.port = port
|
|
61
|
+
self.headless = headless
|
|
62
|
+
self.proxy = proxy
|
|
63
|
+
self.proxy_username = proxy_username
|
|
64
|
+
self.proxy_password = proxy_password
|
|
65
|
+
self.user_data_dir = user_data_dir
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def _get_default_browser_path() -> str:
|
|
69
|
+
"""Get default browser path based on common locations."""
|
|
70
|
+
import os
|
|
71
|
+
|
|
72
|
+
# Common Chrome/Chromium paths
|
|
73
|
+
paths = [
|
|
74
|
+
'/usr/bin/chromium',
|
|
75
|
+
'/usr/bin/chromium-browser',
|
|
76
|
+
'/usr/bin/chrome',
|
|
77
|
+
'/usr/bin/google-chrome',
|
|
78
|
+
'/snap/bin/chromium',
|
|
79
|
+
'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
|
|
80
|
+
'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
for path in paths:
|
|
84
|
+
if os.path.exists(path):
|
|
85
|
+
return path
|
|
86
|
+
|
|
87
|
+
# Default fallback
|
|
88
|
+
return '/usr/bin/chromium'
|
|
89
|
+
|
|
90
|
+
def __repr__(self) -> str:
|
|
91
|
+
return (
|
|
92
|
+
f"BrowserConfig(browser_path='{self.browser_path}', "
|
|
93
|
+
f"port={self.port}, headless={self.headless}, proxy={self.proxy})"
|
|
94
|
+
)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""Browser configuration for Camoufox automation"""
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
import os as os_module
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BrowserConfig:
|
|
8
|
+
"""Configuration for Camoufox browser automation.
|
|
9
|
+
|
|
10
|
+
Uses Camoufox (Playwright Firefox) with advanced fingerprinting and
|
|
11
|
+
anti-detection to bypass Google's bot detection.
|
|
12
|
+
|
|
13
|
+
⚠️ LIMITATIONS:
|
|
14
|
+
- Only 1 keyword supported (no comparison)
|
|
15
|
+
- Only 'today 1-m' timeframe supported
|
|
16
|
+
- Only WORLDWIDE geo supported (no geo filtering)
|
|
17
|
+
- Requires Google account login (first run)
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
headless: Run browser in headless mode (default: False)
|
|
21
|
+
Set to 'virtual' on Linux to use Xvfb
|
|
22
|
+
proxy_server: Proxy server URL (e.g., 'http://proxy.com:8080')
|
|
23
|
+
proxy_username: Proxy username (for authenticated proxies)
|
|
24
|
+
proxy_password: Proxy password (for authenticated proxies)
|
|
25
|
+
user_data_dir: Browser profile directory to persist login session.
|
|
26
|
+
Default: ~/.config/camoufox-pytrends
|
|
27
|
+
humanize: Enable human-like cursor movement (default: True)
|
|
28
|
+
os: Operating system for fingerprint ('windows', 'macos', 'linux')
|
|
29
|
+
geoip: Auto-detect geolocation from proxy IP (default: True if proxy)
|
|
30
|
+
|
|
31
|
+
Example:
|
|
32
|
+
>>> from pytrends_modern import TrendReq, BrowserConfig
|
|
33
|
+
>>> # Simple usage (logs in once, saves session)
|
|
34
|
+
>>> config = BrowserConfig()
|
|
35
|
+
>>> pytrends = TrendReq(browser_config=config)
|
|
36
|
+
>>> pytrends.build_payload(['Python'])
|
|
37
|
+
>>> df = pytrends.interest_over_time()
|
|
38
|
+
>>>
|
|
39
|
+
>>> # With proxy
|
|
40
|
+
>>> config = BrowserConfig(
|
|
41
|
+
... proxy_server='http://proxy.com:8080',
|
|
42
|
+
... proxy_username='user',
|
|
43
|
+
... proxy_password='pass',
|
|
44
|
+
... geoip=True
|
|
45
|
+
... )
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def __init__(
|
|
49
|
+
self,
|
|
50
|
+
headless: bool = False,
|
|
51
|
+
proxy_server: Optional[str] = None,
|
|
52
|
+
proxy_username: Optional[str] = None,
|
|
53
|
+
proxy_password: Optional[str] = None,
|
|
54
|
+
user_data_dir: Optional[str] = None,
|
|
55
|
+
humanize: bool = True,
|
|
56
|
+
os: str = 'linux',
|
|
57
|
+
geoip: bool = True,
|
|
58
|
+
):
|
|
59
|
+
self.headless = headless
|
|
60
|
+
self.proxy_server = proxy_server
|
|
61
|
+
self.proxy_username = proxy_username
|
|
62
|
+
self.proxy_password = proxy_password
|
|
63
|
+
self.user_data_dir = user_data_dir or os_module.path.expanduser('~/.config/camoufox-pytrends-profile')
|
|
64
|
+
self.humanize = humanize
|
|
65
|
+
self.os = os
|
|
66
|
+
self.geoip = geoip if proxy_server else False
|
|
67
|
+
|