How research_quick_wins.py Identifies Keywords in Positions 11-20 for Quick SEO Wins

The research_quick_wins.py script identifies keywords ranking in positions 11-20 by querying Google Search Console for queries with an average position between 11 and 20 and at least 50 impressions over the last 30 days, then enriches this data with DataForSEO and GA4 metrics to prioritize high-impact optimization opportunities.

The research_quick_wins.py file in the TheCraigHewitt/seomachine repository serves as a specialized CLI tool designed to surface actionable SEO opportunities. By targeting keywords currently ranking on page two of Google search results, the script helps marketers focus efforts on content that requires minimal optimization to reach page one visibility.

Defining the Quick Win Criteria

According to the docstring at the top of research_quick_wins.py, the script specifically targets keywords "ranking 11-20 (page 2) that can be pushed to page 1"【3†L3-L6】. This positioning represents the "striking distance" of search results—queries where your content already demonstrates relevance but lacks the authority or optimization to break into the top 10.

The script filters for this range using four specific parameters passed to the Google Search Console API wrapper. These constraints ensure that only viable, high-potential keywords enter the enrichment pipeline.

The GSC Data Retrieval Process

The core identification logic begins with the instantiation of a GoogleSearchConsole client and a call to the get_quick_wins method:

gsc = GoogleSearchConsole()

quick_wins = gsc.get_quick_wins(
    days=30,
    position_min=11,
    position_max=20,
    min_impressions=50
)

This implementation resides in research_quick_wins.py【3†L34-L38】, while the underlying API logic lives in data_sources/modules/google_search_console.py. The method constructs a GSC API request that returns queries meeting all specified numeric thresholds.

Position Filtering Parameters

The script uses two boundary parameters to isolate page-two rankings:

  • position_min=11: Sets the lower bound to the first result on page two
  • position_max=20: Sets the upper bound to the last result on page two

These values ensure the query captures only keywords whose average position falls within the 11-20 range during the specified time period.

Impression Threshold Filtering

The min_impressions=50 parameter acts as a traffic quality filter. By requiring at least 50 impressions over the 30-day window, the script eliminates low-volume keywords that would not generate measurable traffic gains even if optimized to page one. This threshold prevents wasted effort on queries with insufficient search demand.

Data Enrichment and Scoring

After retrieving the initial keyword list from GSC, research_quick_wins.py enhances each opportunity with additional data layers to calculate priority scores.

First, the script optionally pulls DataForSEO rankings to capture exact SERP positions, current ranking URLs, search volume estimates, and keyword difficulty scores【3†L100-L127】.

Second, it retrieves GA4 page performance metrics for the specific URL ranking for each keyword, including pageviews, average engagement time, and bounce rate【3†L44-L60】.

The OpportunityScorer class then processes these combined signals to generate an enhanced opportunity score and priority rating (HIGH, MEDIUM, or LOW), allowing users to tackle the easiest wins with the highest traffic potential first.

Why Page 2 Keywords Represent Quick Wins

Keywords ranking in positions 11-20 offer disproportionate ROI potential compared to lower-ranked queries. Moving a keyword from position 14 to position 6 typically increases click-through rate from approximately 1-2% to roughly 5.5%, representing a nearly threefold traffic increase for that query.

The script leverages the existing authority demonstrated by page-two rankings—Google has already validated the content's relevance—and focuses optimization efforts on closing the small authority or technical gap preventing top-10 placement.

Running the Quick Wins Analysis

Execute the script from the repository root after configuring your .env file with GSC credentials:

python3 research_quick_wins.py

The tool outputs a structured report showing each opportunity's current position, impression count, CTR, and calculated priority level. For automated monitoring, you can schedule this command via cron to run weekly or monthly.

Summary

  • research_quick_wins.py targets keywords ranking in positions 11-20 by calling gsc.get_quick_wins() with position_min=11 and position_max=20 parameters【3†L34-L38】.
  • The script requires a minimum of 50 impressions over 30 days to filter out low-value queries.
  • Raw GSC data gets enriched with DataForSEO (rankings, volume, difficulty) and GA4 (engagement metrics) to calculate opportunity scores【3†L44-L60】【3†L100-L127】.
  • The implementation prioritizes page-two keywords because they require minimal optimization to achieve significant CTR improvements when moved to page one.
  • Core functionality resides in research_quick_wins.py, with supporting modules in data_sources/modules/google_search_console.py and data_sources/modules/opportunity_scorer.py.

Frequently Asked Questions

What API permissions does research_quick_wins.py require?

The script requires read access to Google Search Console property data and optionally Google Analytics 4 (GA4) properties. You must configure OAuth2 credentials or service account keys in your environment variables before running the tool, as the GoogleSearchConsole and GoogleAnalytics clients authenticate against Google's APIs.

How does the script calculate the opportunity priority scores?

The OpportunityScorer class calculates priority by combining multiple signals: current position (closer to 10 scores higher), impression volume (more searches equals higher potential), keyword difficulty (lower difficulty scores favorably), and existing page engagement (high bounce rates may indicate content mismatch). These factors produce an enhanced score out of 100 and assign HIGH, MEDIUM, or LOW priority labels.

Can I adjust the position range to target different ranking brackets?

Yes, you can modify the position_min and position_max arguments in the get_quick_wins() call within research_quick_wins.py. For example, changing these to position_min=8 and position_max=15 would capture the bottom of page one and top of page two, though you would need to edit the source file directly as these values are currently hardcoded in the main execution block.

Why does the script use a 30-day lookback window by default?

The days=30 parameter balances data freshness with statistical significance. Shorter windows might capture volatile ranking fluctuations, while longer windows could include outdated performance data before recent content updates. Thirty days provides sufficient impression volume for most sites while reflecting current search visibility trends.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →