Case study · SEO automation

The SEO kaizen loop

Every Monday a script reads Search Console, picks the pages losing the most clicks they should be winning, and queues them for a rewrite. Eight weeks later it checks whether the rewrite worked. It runs on the data layer of RefreshAgent, which is my own product.

PythonSearch Console APIRefreshAgentWeekly cron
Weeklyscan, unattended
2fixed check-ins per page, at 4 and 8 weeks
3content types tracked separately
1queue, so nothing gets rewritten twice by accident

Problem

Content refresh is usually a guess that nobody checks.

Someone opens Search Console, scrolls, spots a page that looks weak, and rewrites it. Nobody records why that page was chosen. Nobody goes back in two months to see whether it moved. So the team cannot tell a good refresh from a bad one, and the same pages get rewritten again a year later.

Kaizen means small changes, measured, over and over. The measuring is the part people skip, because it happens weeks after the interesting work is done.

How the loop runs

Scan

Pull the last quarter of Search Console data through the RefreshAgent API. Look at three content types separately: articles, dataset pages, and glossary entries, because a good click rate means different things for each.

Pick

Flag a page when it ranks on page one but almost nobody clicks it. That gap is the cheapest win in SEO: the ranking is already there, the title and summary are not doing their job. Pages below a minimum traffic threshold are ignored, since the numbers are noise.

Queue

Each flagged page becomes a record with its starting numbers frozen: clicks, impressions, position, click rate. Without that baseline there is nothing to compare against later.

Measure

Four weeks after a page is republished, and again at eight, the same script pulls fresh numbers and writes them next to the baseline. No one has to remember.

Design choices

Three decisions that make it work.

  • A page can be refreshed more than once. Each attempt adds a new record instead of overwriting the last one. You end up with a history of what was tried on that page, which is what you need when the second rewrite goes worse than the first.
  • Search Console data lags by about three days. The script skips the most recent days rather than treating an incomplete window as a drop. Getting this wrong makes every Monday look like a crash.
  • The scan proposes, a person decides. The loop queues candidates. It does not rewrite anything. The judgement about whether a page deserves the effort stays with a human, and that is where it should sit.

On using my own tool

I built the data layer this runs on.

Getting Search Console data into a script is more annoying than it should be. Service accounts, token refresh, row limits, and an API that answers slowly. I had already solved that in RefreshAgent, so this loop calls RefreshAgent instead of Google directly and gets clean, cached, paginated data back.

Build the boring data layer once as a real product with an API, then write small scripts against it. The scripts stay short enough to read in one sitting.

Site names, page URLs, thresholds tuned to a specific site, and account identifiers are withheld. The loop and its check-in schedule are the transferable parts.