```yaml
product: AlterLab
title: "How to Scrape Google Search Results (SERP) | AlterLab | AlterLab"
comparison_context: "AlterLab is an alternative to Firecrawl, ScrapingBee, and Bright Data."
source_url: https://alterlab.io/how-to/scrape-google-search-results
```

Advanced4 steps

# How to Scrape Google Search Results

Google Search result pages render dynamically, vary by location and device, and frequently update their HTML structure. Extracting organic rankings, featured snippets, and related questions reliably requires a rendering-capable pipeline that handles these variables.

## Step-by-Step Guide

1

### Construct the Google Search URL

Google Search accepts query parameters: `q` for the query, `num` for results per page, `hl` for language, and `gl` for country. Build your URL with the appropriate parameters.

2

### Fetch with JavaScript rendering enabled

Send the search URL to AlterLab with render_js enabled. This ensures JavaScript-dependent elements like People Also Ask boxes are included in the response.

3

### Parse organic results

Extract the organic result elements from the HTML. Google's HTML structure uses consistent data attributes (though class names change) — look for h3 elements within anchor tags in the main results container.

4

### Extract additional SERP features

Parse featured snippets, People Also Ask questions, and knowledge panel data from their respective containers in the HTML.

## Code Example

Python

```
import requests
from bs4 import BeautifulSoup

def scrape_serp(query: str, api_key: str, num_results: int = 10):
    search_url = f"https://www.google.com/search?q={query}&num={num_results}&hl=en"

    response = requests.post(
        "https://alterlab.io/api/v1/scrape",
        headers={"X-API-Key": api_key, "Content-Type": "application/json"},
        json={"url": search_url, "render_js": "auto"},
    )

    html = response.json().get("html", "")
    soup = BeautifulSoup(html, "html.parser")

    results = []
    for h3 in soup.select("h3"):
        parent_a = h3.find_parent("a")
        if parent_a and parent_a.get("href", "").startswith("http"):
            results.append({
                "title": h3.get_text(strip=True),
                "url": parent_a["href"],
            })
    return results
```

Replace `YOUR_API_KEY` with your key from the . No credit card required.

## Try this yourself with AlterLab

Run this tutorial on live websites with AlterLab's API. New accounts get up to 5,000 free requests — no credit card required.

[View API docs](https://alterlab.io/docs/api/rest)

## Frequently Asked Questions

### Can I specify the country and language for SERP results?

Yes — use the `gl` (country) and `hl` (language) query parameters. For example, `gl=gb&hl=en` returns UK English results. AlterLab's proxy network supports geo-targeted requests.

### How often do Google's HTML class names change?

Google updates SERP HTML structure frequently. Build robust selectors based on structural patterns (h3 inside anchor tags) rather than specific class names, and add monitoring to alert you when extraction rates drop.

### Responsible Use

AlterLab is designed for extracting publicly available data. Always review the terms of service for any website you access, respect `robots.txt` directives, and ensure your use case complies with applicable laws in your jurisdiction.

### More tutorials

Browse all [how-to guides](https://alterlab.io/how-to) for web scraping — from beginner extractions to advanced multi-page pipelines.

## Your first scrape. Sixty seconds.

Up to 5,000 free requests — about 5,000 Light, 500 Protected or 250 Dynamic requests. No credit card. 
Just a POST request.

terminal

curl -X POST https://api.alterlab.io/v1/scrape \

-H "X-API-Key: YOUR_KEY" \

-H "Content-Type: application/json" \

-d '{"url": "https://example.com", "formats": ["markdown"]}'

[Start building free](https://alterlab.io/signin)

No credit card required · Up to 5,000 free requests (about 5,000 Light, 500 Protected or 250 Dynamic requests) · Balance never expires