Cómo scrapear resultados de búsqueda de Google con proxies

Aprende a raspar Google SERPs usando proxies residenciales. Ejemplos de código completo en Python, Node.js, y Ir para extraer resultados orgánicos, fragmentos destacados, y la gente también Solicitar datos.

Cómo scrapear resultados de búsqueda de Google con proxies

¿Por qué Scrape Google Resultados de búsqueda?

Google procesa más de 8.500 millones de búsquedas por día, haciendo de sus páginas de resultados del Search Engine (SERPs) la fuente más valiosa de inteligencia competitiva en la web. Los resultados de búsqueda de Google rallando le da acceso a clasificaciones orgánicas, snippets destacados, People Also Ask boxs, packs locales y anuncios pagados — todo en tiempo real.

Ya sea que usted está construyendo un Gasoducto de vigilancia del SERP o realizar una investigación de una sola palabra clave, el acceso programático a los resultados de Google le permite automatizar los flujos de trabajo que tomarían horas para completar manualmente. Los casos de uso común incluyen:

  • Seguimiento de su propia clasificación de palabras clave en los mercados
  • Supervisión de la visibilidad de los competidores para las consultas de objetivos
  • Análisis de la distribución de funciones SERP (snippets, imágenes, videos)
  • Creación de conjuntos de datos para la estrategia de investigación y contenido de SEO

Entender la estructura de Google SERP

Antes de escribir un rascador, usted necesita entender la anatomía de una página de resultados de Google. Un SERP moderno puede contener más de una docena de tipos de resultados distintos:

Entender la estructura de Google SERP
Tipo de resultadoCSS / Marcador de datosDescripción
Resultados orgánicosdiv#search .gResultados estándar de enlace azul con título, URL y snippet
Featured snippetdiv.xpdopenCaja de respuesta mostrada arriba de resultados orgánicos
La gente también preguntadiv.related-question-pairPreguntas de estilo FAQ ampliables
Pack localdiv.VkpGBbMapa con 3 avisos de negocios locales
Panel de conocimientosdiv.kp-wholepageInformación de la Entidad
Resultados de los anunciosdiv.uEierdAnuncios de búsqueda pagados en la parte superior e inferior
Google cambia los nombres de clase con frecuencia. Construya su parser con selectores de retroceso y pruebe regularmente para mantener la extracción confiable.

Configuración de su entorno de limpieza

Para raspar Google fiablemente, necesita tres componentes: un cliente HTTP, una conexión proxy y un analizador HTML. A continuación se presentan ejemplos completos en Python, Node.js, y Go utilizando ProxyHat proxies.

Python Ejemplo

Instala las dependencias primero. El ProxyHat Python SDK simplifica la configuración proxy.

pip install requests beautifulsoup4
import requests
from bs4 import BeautifulSoup
proxy_url = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
proxies = {
    "http": proxy_url,
    "https": proxy_url,
}
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
    "Accept-Language": "en-US,en;q=0.9",
}
def scrape_google(query, num_results=10):
    params = {
        "q": query,
        "num": num_results,
        "hl": "en",
        "gl": "us",
    }
    response = requests.get(
        "https://www.google.com/search",
        params=params,
        headers=headers,
        proxies=proxies,
        timeout=15,
    )
    response.raise_for_status()
    soup = BeautifulSoup(response.text, "html.parser")
    results = []
    for g in soup.select("div#search .g"):
        title_el = g.select_one("h3")
        link_el = g.select_one("a")
        snippet_el = g.select_one(".VwiC3b")
        if title_el and link_el:
            results.append({
                "title": title_el.get_text(),
                "url": link_el["href"],
                "snippet": snippet_el.get_text() if snippet_el else "",
            })
    return results
results = scrape_google("best residential proxies 2026")
for i, r in enumerate(results, 1):
    print(f"{i}. {r['title']}\n   {r['url']}\n")

Node.js Ejemplo

Usando el ProxyHat Node SDK y Cheerio para la prueba:

npm install axios cheerio https-proxy-agent
const axios = require('axios');
const cheerio = require('cheerio');
const { HttpsProxyAgent } = require('https-proxy-agent');
const agent = new HttpsProxyAgent('http://USERNAME:PASSWORD@gate.proxyhat.com:8080');
async function scrapeGoogle(query) {
  const { data } = await axios.get('https://www.google.com/search', {
    params: { q: query, num: 10, hl: 'en', gl: 'us' },
    headers: {
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
      'Accept-Language': 'en-US,en;q=0.9',
    },
    httpsAgent: agent,
    timeout: 15000,
  });
  const $ = cheerio.load(data);
  const results = [];
  $('div#search .g').each((i, el) => {
    const title = $(el).find('h3').text();
    const url = $(el).find('a').attr('href');
    const snippet = $(el).find('.VwiC3b').text();
    if (title && url) {
      results.push({ position: i + 1, title, url, snippet });
    }
  });
  return results;
}
scrapeGoogle('best residential proxies 2026').then(console.log);

Go Ejemplo

Usando el ProxyHat Go SDK y goquery:

package main
import (
    "fmt"
    "log"
    "net/http"
    "net/url"
    "github.com/PuerkitoBio/goquery"
)
func main() {
    proxyURL, _ := url.Parse("http://USERNAME:PASSWORD@gate.proxyhat.com:8080")
    client := &http.Client{
        Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)},
    }
    req, _ := http.NewRequest("GET", "https://www.google.com/search?q=best+residential+proxies&num=10&hl=en&gl=us", nil)
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
    req.Header.Set("Accept-Language", "en-US,en;q=0.9")
    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    doc, _ := goquery.NewDocumentFromReader(resp.Body)
    doc.Find("div#search .g").Each(func(i int, s *goquery.Selection) {
        title := s.Find("h3").Text()
        link, _ := s.Find("a").Attr("href")
        fmt.Printf("%d. %s\n   %s\n\n", i+1, title, link)
    })
}

Paseando diferentes funciones de SERP

Un raspador completo debe manejar más que los resultados orgánicos. Aquí están analizando patrones para las características de SERP más valiosas.

Featured Snippets

# Python: Extract featured snippet
snippet_box = soup.select_one("div.xpdopen")
if snippet_box:
    featured = {
        "type": "featured_snippet",
        "text": snippet_box.get_text(strip=True),
        "source_url": snippet_box.select_one("a")["href"] if snippet_box.select_one("a") else None,
    }

La gente también pregunta

# Python: Extract PAA questions
paa_questions = []
for q in soup.select("div.related-question-pair"):
    question_text = q.select_one("span")
    if question_text:
        paa_questions.append(question_text.get_text(strip=True))

Resultados del paquete local

# Python: Extract local pack
local_results = []
for item in soup.select("div.VkpGBb"):
    name = item.select_one(".dbg0pd")
    rating = item.select_one(".yi40Hd")
    local_results.append({
        "name": name.get_text() if name else "",
        "rating": rating.get_text() if rating else "",
    })

Manejo de bloques de Google y CAPTCHAs

Google defiende activamente contra el raspado automatizado. Sin una infraestructura proxy adecuada, encontrará bloques dentro de docenas de solicitudes. Los principales mecanismos defensivos incluyen:

  • Tasa límite: Demasiados pedidos de una IP activa un código de estado 429
  • CAPTCHA retos: Google sirve reCAPTCHA cuando sospecha automatización
  • reputación IP: Los rangos IP del centro de datos reciben más escrutinio que los IP residenciales
  • Huellas del navegador: Los encabezados perdidos o inconsistentes levantan banderas

Para las estrategias detalladas contra la detección, vea nuestra guía sobre raspando sin ser bloqueado y cómo los sistemas antibot detectan proxies.

Estrategia Proxy recomendada

Los proxies residenciales son esenciales para el raspado de Google sostenido. ProxyHat proxies residenciales proporcionar acceso a millones de IPs en todo 190+ ubicaciones, lo que le permite rotar IPs automáticamente y geo-obtener sus solicitudes. Consejos de configuración clave:

  • Rotar IPs en cada solicitud - nunca reutilizar el mismo IP para consultas de Google consecutivas
  • Agregar retrasos aleatorios entre 2-5 segundos entre solicitudes
  • Coincide con su User-Agent a una versión real del navegador
  • Set hl y gl parámetros consistentes con su ubicación proxy

Referirse al Documentación de ProxyHat para la configuración de autenticación y gestión del período de sesiones.

Construyendo un Raspador de Producción

Pasar de un script a un oleoducto de producción requiere lógica de reingreso, salida estructurada y monitoreo. Aquí está una versión endurecida del raspador Python:

import requests
import time
import random
import json
from bs4 import BeautifulSoup
from datetime import datetime
PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
]
def scrape_serp(query, location="us", retries=3):
    for attempt in range(retries):
        try:
            headers = {
                "User-Agent": random.choice(USER_AGENTS),
                "Accept-Language": "en-US,en;q=0.9",
                "Accept": "text/html,application/xhtml+xml",
            }
            response = requests.get(
                "https://www.google.com/search",
                params={"q": query, "num": 10, "hl": "en", "gl": location},
                proxies={"http": PROXY_URL, "https": PROXY_URL},
                headers=headers,
                timeout=15,
            )
            if response.status_code == 429:
                wait = (attempt + 1) * 10
                print(f"Rate limited. Waiting {wait}s...")
                time.sleep(wait)
                continue
            response.raise_for_status()
            soup = BeautifulSoup(response.text, "html.parser")
            # Check for CAPTCHA
            if "captcha" in response.text.lower() or soup.select_one("#captcha-form"):
                print(f"CAPTCHA detected. Retrying with new IP...")
                time.sleep(random.uniform(5, 10))
                continue
            return parse_serp(soup, query)
        except requests.RequestException as e:
            print(f"Attempt {attempt + 1} failed: {e}")
            time.sleep(random.uniform(2, 5))
    return None
def parse_serp(soup, query):
    results = {
        "query": query,
        "timestamp": datetime.utcnow().isoformat(),
        "organic": [],
        "featured_snippet": None,
        "paa": [],
    }
    # Organic results
    for i, g in enumerate(soup.select("div#search .g")):
        title_el = g.select_one("h3")
        link_el = g.select_one("a")
        snippet_el = g.select_one(".VwiC3b")
        if title_el and link_el:
            results["organic"].append({
                "position": i + 1,
                "title": title_el.get_text(),
                "url": link_el["href"],
                "snippet": snippet_el.get_text() if snippet_el else "",
            })
    # Featured snippet
    snippet_box = soup.select_one("div.xpdopen")
    if snippet_box:
        results["featured_snippet"] = snippet_box.get_text(strip=True)[:500]
    # People Also Ask
    for q in soup.select("div.related-question-pair span"):
        results["paa"].append(q.get_text(strip=True))
    return results
# Usage: scrape a list of keywords
keywords = ["best residential proxies", "proxy for web scraping", "serp tracking tools"]
all_results = []
for kw in keywords:
    result = scrape_serp(kw)
    if result:
        all_results.append(result)
    time.sleep(random.uniform(3, 7))  # Delay between keywords
# Save to JSON
with open("serp_results.json", "w") as f:
    json.dump(all_results, f, indent=2)

Escalando su Scraper SERP

Al monitorear cientos o miles de palabras clave, el raspado de un solo hilo es demasiado lento. Considere estos enfoques de escalado:

  • Solicitudes periódicas: Use asyncio (Python), hilos de trabajo (Node.js), o goroutines (Go) para enviar múltiples solicitudes en paralelo
  • Arquitectura basada en la cola: Empuje palabras clave en una cola (Redis, RabbitMQ) y procesarlas con múltiples trabajadores
  • Gestión directa de la piscina: ProxyHat maneja la rotación automáticamente, pero configura la pegatina de sesión basada en sus necesidades
  • Caché de resultados: Cache SERP data to avoid redundant requests for the same query within a time window

Para obtener una orientación completa sobre la construcción de sistemas escalables de raspado, lea nuestra guía completa de proxies de raspado web.

Consideraciones jurídicas y éticas

Los Términos de Servicio de Google restringen el acceso automatizado. Al raspar Google SERPs, siga estas pautas:

  • Respetar los límites de tarifas y evitar abrumadores servidores de Google
  • Utilice los datos para fines comerciales legítimos (supervisión de la SEO, investigación de mercado)
  • No redistribuya los datos de SERP crudos comercialmente sin entender las leyes aplicables
  • Considere usar las API oficiales de Google donde satisfacen sus necesidades
Revise siempre sus leyes locales en materia de chatarra web y recogida de datos antes de desplegar un raspador SERP a escala.

¿Listo para empezar?

Accede a más de 50M de IPs residenciales en más de 148 países con filtrado impulsado por IA.

Ver preciosProxies residenciales
← Volver al Blog