Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Optimize websites for both traditional search engines (Google, Bing) and AI engines (ChatGPT, Perplexity, Gemini)
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
scripts/related_keywords.py
1#!/usr/bin/env python32"""3Related keywords from Google "searches related to" using DataForSEO API4Get up to 4,680 keyword ideas from Google's related searches56Usage: python3 scripts/related_keywords.py "AI agent" --depth 2 --limit 507"""8import argparse9from dataforseo_api import api_post, get_result, format_count101112def main():13parser = argparse.ArgumentParser(description="Related keywords from Google")14parser.add_argument("keyword", help="Seed keyword")15parser.add_argument("--location", "-loc", type=int, default=2840,16help="Location code (default: 2840 = US)")17parser.add_argument("--depth", "-d", type=int, default=1,18help="Search depth 1-3 (default: 1, max keywords: depth^3 * 10)")19parser.add_argument("--limit", "-l", type=int, default=50,20help="Max results to display (default: 50)")21args = parser.parse_args()2223# Validate depth24if args.depth < 1 or args.depth > 3:25print("Error: depth must be between 1 and 3")26return2728data = [{29"keyword": args.keyword,30"location_code": args.location,31"language_code": "en",32"depth": args.depth,33"limit": 1000 # API limit, we'll filter in display34}]3536response = api_post("dataforseo_labs/google/related_keywords/live", data)37results = get_result(response)3839print(f"keyword: {args.keyword}")40print(f"location: {args.location}")41print(f"depth: {args.depth}")42print()4344if results:45keywords = []46for result in results:47items = result.get("items", [])48for item in items:49kw_data = item.get("keyword_data", {})50keyword = kw_data.get("keyword", item.get("keyword", ""))51volume = kw_data.get("search_volume", item.get("search_volume", 0))52difficulty = kw_data.get("keyword_difficulty", item.get("keyword_difficulty", "N/A"))5354if keyword:55keywords.append({56"keyword": keyword,57"volume": volume if volume is not None else 0,58"difficulty": difficulty59})6061# Sort by volume desc62keywords.sort(key=lambda x: x["volume"], reverse=True)6364# Display limited results65display_keywords = keywords[:args.limit]66print(f"related_keywords[{len(display_keywords)} of {len(keywords)}]{{keyword,volume,difficulty}}:")67for kw in display_keywords:68keyword = kw["keyword"]69volume = format_count(kw["volume"])70difficulty = kw["difficulty"]71print(f" {keyword},{volume},{difficulty}")7273if len(keywords) > args.limit:74print(f"\n... and {len(keywords) - args.limit} more keywords (use --limit to show more)")75else:76print("No related keywords found")7778print()79print("Tip: Higher depth finds more keywords but costs more API credits")80print(f" Depth 1: ~10 keywords, Depth 2: ~100, Depth 3: ~1,000+")818283if __name__ == "__main__":84main()85