Refactor SEO automation into unified CLI application

Major refactoring to create a clean, integrated CLI application:

### New Features:
- Unified CLI executable (./seo) with simple command structure
- All commands accept optional CSV file arguments
- Auto-detection of latest files when no arguments provided
- Simplified output directory structure (output/ instead of output/reports/)
- Cleaner export filename format (all_posts_YYYY-MM-DD.csv)

### Commands:
- export: Export all posts from WordPress sites
- analyze [csv]: Analyze posts with AI (optional CSV input)
- recategorize [csv]: Recategorize posts with AI
- seo_check: Check SEO quality
- categories: Manage categories across sites
- approve [files]: Review and approve recommendations
- full_pipeline: Run complete workflow
- analytics, gaps, opportunities, report, status

### Changes:
- Moved all scripts to scripts/ directory
- Created config.yaml for configuration
- Updated all scripts to use output/ directory
- Deprecated old seo-cli.py in favor of new ./seo
- Added AGENTS.md and CHANGELOG.md documentation
- Consolidated README.md with updated usage

### Technical:
- Added PyYAML dependency
- Removed hardcoded configuration values
- All scripts now properly integrated
- Better error handling and user feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
Kevin Bataille
2026-02-16 14:24:44 +01:00
parent 3b51952336
commit 8c7cd24685
57 changed files with 16095 additions and 560 deletions

View File

@@ -0,0 +1,443 @@
# Multi-Site SEO Analyzer Guide
**Purpose:** Fetch posts from all 3 WordPress sites, analyze titles and meta descriptions, and provide AI-powered optimization recommendations.
**Output:** CSV with detailed analysis + Markdown summary report
---
## Overview
The Multi-Site SEO Analyzer does the following:
1. **Fetches** all published posts from your 3 WordPress sites (mistergeek.net, webscroll.fr, hellogeek.net)
2. **Analyzes** each post's:
- Title (length, power words, numbers, readability)
- Meta description (presence, length, call-to-action)
3. **Scores** posts on SEO best practices (0-100)
4. **Generates** AI recommendations for your top priority posts
5. **Exports** results to CSV for action
---
## Setup
### Step 1: Configure WordPress Access
Update your `.env` file with credentials for all 3 sites:
```bash
# Primary site (fallback for others if not specified)
WORDPRESS_URL=https://www.mistergeek.net
WORDPRESS_USERNAME=your_username
WORDPRESS_APP_PASSWORD=your_app_password
# Site 1: mistergeek.net (uses primary credentials if not specified)
WORDPRESS_MISTERGEEK_URL=https://www.mistergeek.net
WORDPRESS_MISTERGEEK_USERNAME=your_username
WORDPRESS_MISTERGEEK_PASSWORD=your_app_password
# Site 2: webscroll.fr
WORDPRESS_WEBSCROLL_URL=https://www.webscroll.fr
WORDPRESS_WEBSCROLL_USERNAME=your_username
WORDPRESS_WEBSCROLL_PASSWORD=your_app_password
# Site 3: hellogeek.net
WORDPRESS_HELLOGEEK_URL=https://www.hellogeek.net
WORDPRESS_HELLOGEEK_USERNAME=your_username
WORDPRESS_HELLOGEEK_PASSWORD=your_app_password
# OpenRouter API (for AI recommendations)
OPENROUTER_API_KEY=your_key
```
**Note:** If a site's credentials are not specified, the script uses the primary site credentials.
### Step 2: Verify Your .env
```bash
cat .env | grep -E "WORDPRESS|OPENROUTER"
```
---
## Usage
### Basic Usage (with AI recommendations)
```bash
python scripts/multi_site_seo_analyzer.py
```
This will:
- Fetch all posts from 3 sites
- Analyze each post
- Generate AI recommendations for top 10 worst-scoring posts
- Export results to CSV and Markdown
### Include Draft Posts
```bash
python scripts/multi_site_seo_analyzer.py --include-drafts
```
Analyzes both published and draft posts. Useful for:
- Optimizing posts before publishing
- Recovering removed content saved as drafts
- Getting full picture of all content
- CSV will show `status` column (publish/draft)
### Skip AI (Save Cost)
```bash
python scripts/multi_site_seo_analyzer.py --no-ai
```
Analyzes posts without AI recommendations. Good for:
- Quick overview
- Sites with >500 posts (AI costs add up)
- Budget testing
### Generate AI for Top 20 Posts
```bash
python scripts/multi_site_seo_analyzer.py --top-n 20
```
AI recommendations for 20 worst-scoring posts instead of 10.
### Combine Options
```bash
# Analyze published + drafts with AI for top 20
python scripts/multi_site_seo_analyzer.py --include-drafts --top-n 20
# Analyze drafts only (then filter in Excel to status=draft)
python scripts/multi_site_seo_analyzer.py --include-drafts --no-ai
```
### Custom Output File
```bash
python scripts/multi_site_seo_analyzer.py --output output/custom_report.csv
```
---
## Output Files
### 1. CSV Report: `seo_analysis_TIMESTAMP.csv`
Contains all analyzed posts with columns:
| Column | Description |
|--------|-------------|
| `site` | Website (mistergeek.net, webscroll.fr, hellogeek.net) |
| `post_id` | WordPress post ID |
| `title` | Post title |
| `slug` | Post slug |
| `url` | Full post URL |
| `meta_description` | Current meta description |
| `title_score` | Title SEO score (0-100) |
| `title_issues` | Title problems (too short, no power words, etc.) |
| `title_recommendations` | How to improve title |
| `meta_score` | Meta description SEO score (0-100) |
| `meta_issues` | Meta description problems |
| `meta_recommendations` | How to improve meta |
| `overall_score` | Combined score (40% title + 60% meta) |
| `ai_recommendations` | Claude-generated specific recommendations |
### 2. Summary Report: `seo_analysis_TIMESTAMP_summary.md`
Human-readable markdown with:
- Overall statistics (total posts, average score, cost)
- Priority issues (missing meta, weak titles, weak descriptions)
- Per-site breakdown
- Top 5 posts to optimize on each site
- Legend explaining scores
---
## Understanding Scores
### Title Score (0-100)
**What's analyzed:**
- Length (target: 50-70 characters)
- Power words (best, complete, guide, ultimate, essential, etc.)
- Numbers (top 5, 2025, etc.)
- Special characters that might break rendering
**Optimal title example:**
"The Complete 2025 Guide to VPN Services (Updated)"
- Length: 57 characters ✓
- Power words: "Complete", "Guide" ✓
- Numbers: "2025" ✓
- Score: 95/100
### Meta Description Score (0-100)
**What's analyzed:**
- Presence (missing = 0 score)
- Length (target: 120-160 characters)
- Call-to-action (learn, discover, find, check, etc.)
**Optimal meta example:**
"Discover the best VPN services for 2025. Compare 50+ options, learn about encryption, and find the perfect VPN for your needs. Updated monthly."
- Length: 149 characters ✓
- CTA: "Discover", "Compare", "learn", "find" ✓
- Score: 90/100
### Overall Score (0-100)
```
Overall = (Title Score × 40%) + (Meta Score × 60%)
```
Meta description weighted heavier because it directly impacts click-through rates from search results.
---
## Action Plan
### 1. Review Results
```bash
# Open the summary report
open output/reports/seo_analysis_*.md
# Or open the detailed CSV
open output/reports/seo_analysis_*.csv
```
### 2. Prioritize by Score
**High Priority (Score < 50):**
- Title issues OR missing/weak meta
- Implement AI recommendations immediately
- Estimated impact: 10-20% CTR improvement
**Medium Priority (Score 50-75):**
- Minor title or meta issues
- Apply recommendations when convenient
- Estimated impact: 5-10% CTR improvement
**Low Priority (Score > 75):**
- Already optimized
- Only update if major content changes
### 3. Batch Implementation
**For WordPress:**
1. Go to WordPress admin
2. Edit post
3. Update title (if recommended)
4. Update meta description in Yoast SEO or All in One SEO:
- Yoast: Bottom of editor → "SEO" tab → Meta description
- AIOSEO: Right sidebar → "General" → Description
5. Save post
**OR use bulk operations** if your SEO plugin supports it.
### 4. Monitor Impact
Re-run the analyzer in 30 days:
```bash
python scripts/multi_site_seo_analyzer.py
```
Track improvements:
- Average score increase
- Fewer posts with score < 50
- Posts moved from "Missing meta" to "Strong meta"
---
## Cost Estimation
### AI Recommendation Costs
Using Claude 3.5 Sonnet via OpenRouter ($3 input / $15 output per 1M tokens):
**Scenario 1: 10 posts with AI**
- ~2,500 input tokens per post × 10 = 25,000 input tokens
- ~500 output tokens per post × 10 = 5,000 output tokens
- Cost: (25,000 × $3 + 5,000 × $15) / 1,000,000 = **$0.105** (~11¢)
**Scenario 2: 50 posts with AI**
- 125,000 input + 25,000 output tokens
- Cost: **$0.525** (~52¢)
**Scenario 3: No AI (--no-ai flag)**
- Cost: **$0.00**
### Monthly Scenarios
| Scenario | Frequency | Cost/Month |
|----------|-----------|-----------|
| No AI | Weekly | $0 |
| 10 posts/week | Weekly | ~€0.40 |
| 20 posts/week | Weekly | ~€0.80 |
| 50 posts/month | Once | ~€0.50 |
---
## Troubleshooting
### "Connection refused" on a site
**Problem:** WordPress site is down or credentials are wrong.
**Solutions:**
1. Check site URL is correct (https, www vs no-www)
2. Verify credentials: Try logging in manually
3. Check if site has REST API enabled: `https://yoursite.com/wp-json/`
4. Skip that site temporarily (remove from config, re-run)
### "No posts found"
**Problem:** API returns 0 posts.
**Solutions:**
1. Verify credentials have permission to read posts
2. Check if posts exist on the site
3. Try without authentication (remove from config)
4. Check if REST API is disabled
### AI recommendations are empty
**Problem:** OpenRouter API call failed.
**Solutions:**
1. Verify OPENROUTER_API_KEY is set: `echo $OPENROUTER_API_KEY`
2. Check API key is valid (not expired, has credits)
3. Try with --no-ai flag to verify the rest works
4. Check internet connection
### Memory issues with 1000+ posts
**Problem:** Script runs out of memory.
**Solutions:**
1. Run --no-ai version first (lighter)
2. Analyze one site at a time (modify config temporarily)
3. Increase system memory or close other apps
---
## Advanced Usage
### Analyze One Site
Temporarily comment out sites in config.py or create a custom script:
```python
from scripts.multi_site_seo_analyzer import MultiSiteSEOAnalyzer
from scripts.config import Config
analyzer = MultiSiteSEOAnalyzer()
# Override to just one site
analyzer.sites_config = {
'mistergeek.net': Config.WORDPRESS_SITES['mistergeek.net']
}
analyzer.run(use_ai=True, top_n=20)
```
### Export to Google Sheets
1. Download the CSV
2. Open Google Sheets
3. File → Import → Upload CSV
4. Share link with team
5. Filter by site or score
6. Add "Completed" checkbox column
7. Track progress as you optimize
### Integrate with WordPress via Zapier
1. Export CSV from analyzer
2. Use Zapier to trigger WordPress post updates
3. Automatically update meta descriptions for high-priority posts
4. (Advanced - requires Zapier Pro)
---
## Examples
### Example 1: Post with Low Title Score
```
Title: "VPN"
Title Issues: Too short (3), Missing power word, No number
Title Score: 10/100
Recommendation: Expand title to include benefit and year
Better Title: "Best VPN Services 2025: Complete Guide"
```
### Example 2: Post with Missing Meta
```
Meta Description: [MISSING]
Meta Score: 0/100
AI Recommendation:
"Write a meta description: 'Learn about the best VPN services for 2025.
Compare 50+ providers, understand encryption, and choose the right VPN
for your needs. Updated weekly.' (150 characters)"
```
### Example 3: Strong Post (No Changes Needed)
```
Title: "The Complete Guide to NordVPN: Features, Pricing, and Reviews"
Title Issues: None
Title Score: 95/100
Meta: "Comprehensive review of NordVPN including speed tests, security features, pricing plans, and user reviews. Find out if NordVPN is right for you."
Meta Issues: None
Meta Score: 95/100
Overall Score: 95/100
Status: No changes needed ✓
```
---
## FAQ
**Q: How often should I run this?**
A: Monthly or after publishing 10+ new posts. More frequent for highly competitive topics.
**Q: Will changing titles affect SEO?**
A: No, titles can be improved without penalty. The URL stays the same, so search rankings are preserved.
**Q: Should I update all weak meta descriptions?**
A: Prioritize posts with traffic. Update high-traffic posts first for maximum impact.
**Q: Can I use this on a site with 5000+ posts?**
A: Yes, but consider:
- Using --no-ai on first run (faster)
- Running once per month instead of weekly
- Focusing AI analysis on high-traffic posts only
**Q: What if my site uses a different SEO plugin?**
A: The script looks for common meta description fields. If it finds nothing, add one manually. Plugin doesn't matter; the meta description HTML is standard.
---
## Next Steps
1. **Run the analyzer:** `python scripts/multi_site_seo_analyzer.py`
2. **Review the report:** Open `output/reports/seo_analysis_*_summary.md`
3. **Prioritize:** Identify posts with score < 50
4. **Implement:** Update titles and meta descriptions
5. **Track:** Re-run in 30 days to measure improvement
6. **Monitor:** Watch Google Search Console for CTR improvements
Ready to optimize? Let's go! 🚀