How to Automate SEO Content Briefs with Python, SERP Data, and an LLM
Most content briefs are still assembled by hand: an SEO opens five competitor tabs, eyeballs their headings, copies a few “People Also Ask” questions into a doc, guesses a word count, and ships it to a writer. It takes 45–90 minutes per brief, the output is inconsistent, and it quietly bottlenecks the entire content pipeline. If you publish more than a handful of articles a month, the brief is the single most automatable step you are still doing manually.
This post walks through a Python pipeline that builds a data-grounded content brief in under a minute: it scrapes the live SERP for your target keyword, extracts the heading structure and questions that already rank, computes a defensible target word count, and hands the structured signal to an LLM that drafts the brief. The LLM never invents the SERP — it only summarizes evidence you collected. That separation is the whole trick, and it is what keeps the output from becoming generic AI filler.
Why a brief is the right thing to automate
A brief is a constrained, structured task with a clear correctness signal, which makes it a far safer automation target than full-article generation. You are not asking a model to be creative; you are asking it to compress a pile of competitor data into an outline a human writer can execute. The facts come from the SERP, the judgment about what to cover comes from frequency analysis, and the LLM only handles the language. When something looks wrong in the output, you can trace it back to a specific scraped page rather than to a hallucination.
This is the same philosophy behind automating keyword research with the Search Console API: let machines do the gathering and the counting, and reserve human attention for the strategic calls a model cannot make.
Step 1 — Pull the live SERP for your keyword
The brief is only as good as the SERP snapshot behind it, so start with the top 10 organic results for the exact query. Scraping Google directly is brittle and gets you blocked, so route the request through a SERP API or an unblocking proxy. The output you want is a clean list of ranking URLs.
import requests
def fetch_serp(keyword, api_key, country="us"):
resp = requests.get(
"https://api.brightdata.com/serp",
params={"q": keyword, "gl": country, "num": 10},
headers={"Authorization": f"Bearer {api_key}"},
timeout=30,
)
resp.raise_for_status()
results = resp.json()["organic"]
return [r["link"] for r in results if "link" in r]
Keep the country parameter explicit. A brief built off US results is misleading if the page is meant to rank in the UK or India, and the heading patterns can differ more than you would expect between locales.
Step 2 — Extract headings and questions from the ranking pages
For each ranking URL, fetch the HTML and pull the on-page structure: the H1, every H2 and H3, and the body length. The heading outline of the pages that already rank is the closest thing you have to Google’s revealed preference for how this topic should be organized.
from bs4 import BeautifulSoup
def extract_structure(html):
soup = BeautifulSoup(html, "html.parser")
for tag in soup(["script", "style", "nav", "footer"]):
tag.decompose()
headings = [
{"level": h.name, "text": h.get_text(strip=True)}
for h in soup.find_all(["h1", "h2", "h3"])
if h.get_text(strip=True)
]
words = len(soup.get_text(" ", strip=True).split())
return {"headings": headings, "word_count": words}
Run this across all ten pages and you have a corpus: every subheading your competitors use, plus the distribution of article lengths. Two cheap computations turn that corpus into brief inputs. First, a target word count — the median of the ten lengths is more robust than the mean, which gets dragged around by one bloated 6,000-word outlier. Second, a topic frequency map: normalize the heading text (lowercase, strip stopwords) and count how often each concept appears across pages. A subtopic covered by seven of ten ranking pages is effectively mandatory; one that appears once is optional color.
import statistics
from collections import Counter
def aggregate(structures):
counts = [s["word_count"] for s in structures]
topics = Counter()
for s in structures:
seen = {h["text"].lower() for h in s["headings"]}
topics.update(seen)
return {
"target_words": int(statistics.median(counts)),
"common_topics": [t for t, n in topics.most_common(25) if n >= 3],
}
Mining the “People Also Ask” box and related searches in the same pass gives you a ready-made FAQ section. Those questions are real queries Google associates with the topic, and answering them directly is one of the cleaner paths into AI Overviews and ChatGPT citations — a point worth pairing with a deliberate generative engine optimization playbook once the brief is written.
Step 3 — Hand the evidence to the LLM
Only now does the model enter, and its job is narrow: turn structured evidence into a readable brief. Pass the aggregated topics, the target word count, and the questions as data, and constrain the prompt so the model cannot wander outside what you gave it.
import json
from anthropic import Anthropic
def write_brief(keyword, agg, questions):
client = Anthropic()
prompt = f"""You are an SEO content strategist. Using ONLY the data below,
write a content brief for an article targeting "{keyword}".
Target length: {agg['target_words']} words.
Subtopics competitors cover (frequency-ranked): {json.dumps(agg['common_topics'])}
Questions to answer: {json.dumps(questions)}
Output: a recommended H1, an ordered H2/H3 outline grouping the subtopics
logically, the search intent in one sentence, and 3-5 FAQ questions.
Do not invent statistics or sources."""
msg = client.messages.create(
model="claude-opus-4-8",
max_tokens=1500,
messages=[{"role": "user", "content": prompt}],
)
return msg.content[0].text
The phrase “using ONLY the data below” is doing real work. Without it the model pads the outline with plausible-sounding sections no competitor actually covers, which is exactly the generic, non-differentiated content Google’s guidance warns against. With the constraint, the outline stays anchored to observed SERP reality and the writer gets a brief they can trust.
Step 4 — Wire it into a repeatable pipeline
The four functions above are a pipeline, not a script. Drop a list of target keywords in at the top, loop, and write each brief to a Google Doc, Notion page, or your CMS. Teams that prefer a visual orchestration layer can port the same logic into n8n: an HTTP node for the SERP call, a Code node for extraction and aggregation, an LLM node for drafting, and a Docs node to file the result. Either way the architecture is identical — gather, count, draft, store.
One guardrail matters at scale: deduplicate against your own site before generating. If you are about to brief an article that overlaps an existing URL, you are manufacturing a cannibalization problem. Run new target keywords through a similarity check against your published content — the same approach used to detect content cannibalization with vector embeddings — and skip or merge anything that scores too close.
Results and what to measure
In practice this pipeline collapses brief creation from roughly an hour of manual work to about 40 seconds of compute and a few cents of API cost. The more valuable outcome is consistency: every brief now carries the same evidence base — a median-derived word target, a frequency-ranked topic list, and SERP-sourced questions — instead of depending on which analyst built it and how much coffee they had. Writers stop guessing at scope, and editors review against a fixed rubric.
Track three things to confirm it is working. First, brief-to-publish time, which should drop sharply. Second, topic coverage — spot-check that published articles actually address the high-frequency subtopics the brief flagged. Third, ranking outcomes at 60–90 days, comparing automated-brief articles against your historical baseline. Watch for over-optimization: if every brief converges on the same outline because every competitor copied each other, the model will faithfully reproduce a saturated SERP. The fix is human judgment at the keyword-selection stage, which is exactly where you want analysts spending their time. Pair this with automated competitor content gap analysis to make sure you are briefing topics with genuine opportunity, not just chasing pages that already rank.
Takeaways
Content briefs are the highest-leverage automation in most content operations because they sit upstream of every article and are structured enough to automate safely. The durable pattern is to keep the LLM downstream of real data: scrape the SERP, count what ranks, and let the model handle language only. That keeps your briefs grounded, your writers fast, and your content out of the generic-AI-filler bucket that Google is actively demoting.
Found this useful? Bookmark SEO Automation Club and check back for a new automation playbook every week — we ship working code and real workflows, not listicles.
Frequently Asked Questions
Do I need a paid SERP API, or can I scrape Google directly?
You can scrape directly for a handful of queries, but Google blocks automated requests quickly and serves personalized or CAPTCHA-gated results that corrupt your data. A SERP API or unblocking proxy returns consistent, location-accurate results and is worth the few cents per query once you are briefing at any volume.
Will LLM-generated briefs trigger Google’s spam policies?
The brief is an internal planning artifact, not published content, so it is not what Google evaluates. The risk lies in publishing thin, model-generated articles at scale. Because this pipeline grounds the outline in real SERP evidence and leaves the actual writing to humans, it supports differentiated content rather than the scaled, low-value pages the policies target.
How many ranking pages should I analyze per brief?
The top 10 organic results is the standard window — enough to compute a stable median word count and a meaningful topic-frequency signal without drowning in noise. Going to 20 rarely changes the brief and roughly doubles your scraping cost and time.
Which LLM should I use for the drafting step?
Any capable instruction-following model works because the task is summarization, not reasoning over ambiguous data. Choose based on cost and latency at your volume; the quality of the brief depends far more on the SERP evidence you feed in than on which frontier model phrases the outline.
