Perché Scrape Google Search Results?
Google elabora oltre 8,5 miliardi di ricerche al giorno, rendendo le pagine dei risultati del motore di ricerca (SERP) la fonte più preziosa di intelligenza competitiva sul web. Scraping Google risultati di ricerca ti dà accesso a classificazioni organiche, frammenti presenti, persone anche chiedere scatole, pacchetti locali, e pagati annunci - tutto in tempo reale.
Se stai costruendo un pipeline di monitoraggio SERP o eseguire una ricerca di parole chiave, l'accesso programmatico ai risultati di Google consente di automatizzare i flussi di lavoro che richiederebbero ore per completare manualmente. I casi di uso comune includono:
- Tracciare le proprie classifiche di parole chiave sui mercati
- Monitoraggio della visibilità dei concorrenti per le domande di destinazione
- Analisi della distribuzione delle funzionalità SERP (snippet, immagini, video)
- Dataset di costruzione per la ricerca SEO e la strategia dei contenuti
Comprensione della struttura SERP di Google
Prima di scrivere un raschietto, è necessario capire l'anatomia di una pagina di risultati di Google. Un moderno SERP può contenere oltre una dozzina di tipi di risultato distinti:
| Tipo di risultato | CSS / Data Marker | Descrizione |
|---|---|---|
| Risultati organici | div#search .g | Risultati standard blue-link con titolo, URL e snippet |
| Snippet in evidenza | div.xpdopen | Scatola di risposta visualizzata sopra i risultati organici |
| La gente chiede anche | div.related-question-pair | Domande sullo stile delle FAQ |
| Pacchetto locale | div.VkpGBb | Mappa con 3 annunci aziendali locali |
| Pannello di conoscenza | div.kp-wholepage | Informazioni sull'ingresso sidebar |
| Risultati pubblicitari | div.uEierd | Annunci di ricerca a pagamento in alto e in basso |
Google cambia nomi di classe frequentemente. Costruisci il tuo parser con selettori fallback e prova regolarmente per mantenere l'estrazione affidabile.
Impostare il tuo ambiente di scorrimento
Per demolire Google in modo affidabile, è necessario tre componenti: un client HTTP, una connessione proxy e un parser HTML. Qui di seguito sono esempi completi in Python, Node.js e Go utilizzando Prossidi di ProxyHat.
Esempio di Python
Installare prima le dipendenze. The ProxyHat Python SDK semplifica la configurazione del proxy.
pip install requests beautifulsoup4import 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")Esempio Node.js
Usare il SDK del nodo del proxy e Cheerio per la parasing:
npm install axios cheerio https-proxy-agentconst 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);Vai Esempio
Usare il ProxyHat Go SDK e 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)
})
}Caratteristiche SERP differenti
Un raschietto completo dovrebbe gestire più di soli risultati organici. Ecco i modelli di parsing per le più preziose caratteristiche SERP.
In primo piano
# 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 chiede anche
# 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))Risultati del pacchetto locale
# 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 "",
})Gestione di Google Blocks e CAPTCHAs
Google difende attivamente contro la raschiatura automatizzata. Senza una corretta infrastruttura proxy, si incontrano blocchi all'interno di decine di richieste. I principali meccanismi difensivi includono:
- Tasso di limitazione: Troppe richieste da un IP innesca un codice di stato 429
- CAPTCHA sfide: Google serve reCAPTCHA quando sospetta automazione
- reputazione IP: Gli intervalli IP del Datacenter ricevono più controllo rispetto agli IP residenziali
- Impronte del browser: Intestazioni mancanti o inconsistenti sollevano bandiere
Per le strategie di anti-detezione dettagliate, vedere la nostra guida su raschiamento senza bloccarsi e come i sistemi anti-bot rilevano i proxy.
Strategia proxy consigliata
I proxy residenziali sono essenziali per la raccolta continua di Google. Prossi residenziali ProxyHat fornire l'accesso a milioni di IP attraverso 190+ sedi, consentendo di ruotare gli IP automaticamente e geo-target le vostre richieste. Consigli di configurazione chiave:
- Ruotare gli IP su ogni richiesta - non riutilizzare mai lo stesso IP per domande consecutive di Google
- Aggiungi ritardi casuali tra 2-5 secondi tra le richieste
- Abbina il tuo User-Agent a una vera versione del browser
- Set
hleglparametri coerenti con la posizione del proxy
Fare riferimento al Documentazione ProxyHat per la configurazione di autenticazione e la gestione delle sessioni.
Costruire un Graffio di Produzione
Passare da uno script a una pipeline di produzione richiede riprova logica, output strutturato e monitoraggio. Ecco una versione indurita del raschietto 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)Scala il tuo grattacielo SERP
Quando il monitoraggio di centinaia o migliaia di parole chiave, la raschiatura single-threaded è troppo lenta. Considerare questi approcci di scaling:
- Richieste ricorrenti: Utilizzare l'asincrona (Python), i fili del lavoratore (Node.js), o le goroutine (Go) per inviare più richieste in parallelo
- Architettura basata su queue: Spingere parole chiave in una coda (Redis, RabbitMQ) e processarli con più lavoratori
- Gestione della piscina proxy: ProxyHat gestisce automaticamente la rotazione, ma configura la stabilità di sessione in base alle tue esigenze
- Caching del risultato: Cache SERP dati per evitare richieste ridondanti per la stessa richiesta entro una finestra di tempo
Per una guida completa sulla costruzione di sistemi di raschiamento scalabili, leggi il nostro guida completa ai proxy di raschiamento web.
Considerazioni giuridiche ed etiche
Le Condizioni di servizio di Google limitano l'accesso automatizzato. Quando si raschiano Google SERPs, seguire queste linee guida:
- Rispetta i limiti della velocità e evita di schiacciare i server di Google
- Utilizzare i dati per scopi commerciali legittimi (controllo SEO, ricerca di mercato)
- Non ridistribuire dati SERP grezzi commercialmente senza comprendere le leggi applicabili
- Considera di utilizzare le API ufficiali di Google in cui soddisfano le tue esigenze
Controllare sempre le leggi locali per quanto riguarda la raccolta di dati e rottami web prima di distribuire un raschietto SERP in scala.




