Jak Google wykrywa skanery SERP
Google mocno inwestuje w ochronę wyników wyszukiwania przed automatycznym dostępem. Zanim unikniesz bloków, musisz zrozumieć metody wykrywania stosowane przez Google. Każda metoda skierowana jest do innego sygnału, a skuteczne zeskrobanie SERP wymaga odpowiedzi na wszystkie jednocześnie.
Kompletny przegląd architektury szlifowania SERP z proxy, zobacz nasz SERP skrobanie z przewodnikiem proxy.
Wykrywanie oparte na IP-
Pierwszą linią obrony jest analiza IP. Google śledzi wolumen zapytań na adres IP i oznacza te, które przekraczają normalne ludzkie wzorce wyszukiwania. Sygnały szczególne obejmują:
- Częstotliwość składania wniosków: Ponad kilka wyszukiwań na minutę z jednego IP powoduje ograniczenie prędkości
- Reputacja IP: Znane zakresy danych IP otrzymują natychmiastową kontrolę
- Niespójność geograficzna: IP z Niemiec sprawia, że angielski pytania adresowane do użytkowników podnosi flagi
- Analiza ASN: Google identyfikuje bloki IP należące do dostawców usług hostingowych i dostawców usług internetowych
Drukowanie odcisków palców w przeglądarce
Poza adresami IP Google bada sam wniosek o znaki automatyzacji:
| Sygnał | Co sprawdza Google | Czerwona flaga |
|---|---|---|
| User- Agent | Przeglądarka i łańcuch identyfikacji systemu operacyjnego | Brakujące, przestarzałe lub niezgodne z innymi nagłówkami |
| Akceptuj nagłówki | Preferencje dotyczące rodzaju zawartości | Brakujące wartości akcept- Język lub niestandardowe |
| Odcisk palca TLS | Charakterystyka uścisku dłoni SSL / TLS | Odciski palców pasujące do znanych bibliotek HTTP (żądania, urllib) |
| Wykonanie JavaScript | Zachowanie skryptu po stronie klienta | Brak wykonania JavaScript (detekcja bez głowy) |
| Zachowanie plików cookie | Akceptacja plików cookie i zarządzanie nimi | Wnioski bez plików cookie lub identycznych wzorów plików cookie |
Aby głębiej przyjrzeć się tym technikom, przeczytaj nasz artykuł na temat jak systemy anty-bot wykrywają proxy.
Analiza behawioralna
Google analizuje wzorce we wszystkich wnioskach o wykrycie automatyzacji:
- Prośba o terminy: Doskonale spójne odstępy pomiędzy żądaniami (np. dokładnie 3 sekundy od siebie) są nienaturalne
- Wzory zapytań: Rozdrabnianie słów kluczowych alfabetycznie lub w przewidywalnych sekwencjach wygląda automatycznie
- Zachowanie sesji: Prawdziwi użytkownicy przeglądają wiele stron, klikają wyniki i spędzają czas czytając - scrappers po prostu pobrać SERP
- Wzory głośności: Nagłe skoki wolumenu zapytań z powiązanych IP sugerują skoordynowane skrobanie
Trzy warstwy strategii antyblokowej
Unikanie bloków Google wymaga podejścia warstwowego. Żadna technika nie jest wystarczająca.
Warstwa 1: Infrastruktura Proxy
Twój wybór proxy jest podstawą twojej antyblokowej strategii. ProxyHat proxy mieszkalne zapewnienie zróżnicowania IP i poziomu zaufania niezbędnego do trwałego skrobania SERP.
Warstwa 2: Konfiguracja żądania
Każde żądanie HTTP musi wyglądać tak, jakby pochodziło z prawdziwej przeglądarki. Nagłówki, ciasteczka i czas wszystko musi być realistyczne.
Warstwa 3: Wzory behawioralne
Ogólny wzór działania musi naśladować naturalne zachowanie wyszukiwania. Oznacza to randomizowane opóźnienia, zróżnicowane sekwencje zapytań oraz odpowiednie wolumeny zapytań.
Residential Proxies: Twoja pierwsza obrona
Najbardziej efektowna zmiana, jaką możesz wprowadzić, to przełączenie z datacenter na proxy mieszkanioweOto dlaczego IP mieszkaniowe zasadniczo różnią się od perspektywy Google:
- IP mieszkaniowe należą do prawdziwych dostawców usług internetowych (Comcast, AT & T, BT, Deutsche Telekom), a nie do dostawców usług w chmurze
- Google nie może blokować zakresów IP bez blokowania legalnych użytkowników
- Każdy IP ma historię przeglądania i reputację zbudowaną przez jego rzeczywistego użytkownika
- Lokalne IPP wspierają ukierunkowanie geologiczne na poziomie miast w odniesieniu do dokładnych lokalizacji SERP
Konfiguracja proxy dla skanowania SERP
import requests
# ProxyHat residential proxy with automatic rotation
PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
session = requests.Session()
session.proxies = {
"http": PROXY_URL,
"https": PROXY_URL,
}
# Each request automatically gets a new residential IP
response = session.get(
"https://www.google.com/search",
params={"q": "best proxy service", "num": 10, "hl": "en", "gl": "us"},
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": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
"DNT": "1",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
},
timeout=15,
)Patrz Dokumentacja ProxyHat dla zaawansowanych ustawień rotacji i sesji.
Realistyczne nagłówki żądań
Niekompletne lub niespójne nagłówki są jednym z najczęstszych powodów scrapers zostają zablokowane. Oto kompletny, realistyczny zestaw nagłówków:
import random
# Rotate between realistic User-Agent strings
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 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3 Safari/605.1.15",
]
def get_headers():
ua = random.choice(USER_AGENTS)
headers = {
"User-Agent": ua,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
"DNT": "1",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"Cache-Control": "max-age=0",
}
# Firefox has different Sec-Ch headers
if "Firefox" not in ua:
headers["Sec-Ch-Ua"] = '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"'
headers["Sec-Ch-Ua-Mobile"] = "?0"
headers["Sec-Ch-Ua-Platform"] = '"Windows"' if "Windows" in ua else '"macOS"'
return headersNależy zawsze aktualizować struny User- Agent w aktualnych wersjach przeglądarki. Wysłanie Chrome 90 User- Agent w 2026 jest natychmiastową czerwoną flagą.
Rate Limiting and Request Timing
Wzorce twoich żądań są równie ważne, jak same prośby. Oto sprawdzone strategie czasowe:
Opóźnienia losowe
Nigdy nie stosuj stałych przerw między wnioskami. Zamiast tego, losować opóźnienia naśladować ludzkie zachowanie wyszukiwania:
import time
import random
def human_delay():
"""Generate a realistic delay between searches."""
# Base delay: 3-8 seconds (normal browsing pace)
base = random.uniform(3, 8)
# Occasionally add longer pauses (simulating reading results)
if random.random() < 0.15:
base += random.uniform(10, 30)
# Rare very short delays (rapid refinement searches)
if random.random() < 0.05:
base = random.uniform(1, 2)
return base
# Usage in scraping loop
for keyword in keywords:
result = scrape_serp(keyword)
delay = human_delay()
time.sleep(delay)Wytyczne dotyczące wielkości wniosków
| Typ proxy | Bezpieczne wnioski / Min na OD | Max Równoczesne IP |
|---|---|---|
| Mieszkalne (obrotowe) | 1-2 | Nieograniczona (pula obraca się) |
| Mieszkanie (sesja lepka) | 1 na 30 | Na podstawie wielkości basenu |
| Datacenter | 1 na 60 | Ograniczone przez liczbę IP |
Obsługa CAPTCHA i bloków
Nawet z najlepszych środków ostrożności, czasami napotkasz bloki. Zbuduj swój scraper, aby obsługiwać je z wdziękiem.
Wykrywanie bloków
def is_blocked(response):
"""Check if Google has blocked or challenged the request."""
# HTTP 429: Rate limited
if response.status_code == 429:
return "rate_limited"
# HTTP 503: Service unavailable (temporary block)
if response.status_code == 503:
return "service_unavailable"
text = response.text.lower()
# CAPTCHA detection
if "captcha" in text or "recaptcha" in text:
return "captcha"
# Unusual traffic message
if "unusual traffic" in text or "automated queries" in text:
return "unusual_traffic"
# Empty or suspicious results
if "did not match any documents" in text and len(text) < 5000:
return "empty_suspicious"
return NoneStrategia pobierania
import time
import random
def scrape_with_retry(keyword, max_retries=3):
"""Scrape a SERP with automatic retry on blocks."""
for attempt in range(max_retries):
proxy_url = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
proxies = {"http": proxy_url, "https": proxy_url}
response = requests.get(
"https://www.google.com/search",
params={"q": keyword, "num": 10, "hl": "en", "gl": "us"},
headers=get_headers(),
proxies=proxies,
timeout=15,
)
block_type = is_blocked(response)
if block_type is None:
return parse_results(response.text)
if block_type == "rate_limited":
# Exponential backoff
wait = (2 ** attempt) * 5 + random.uniform(0, 5)
print(f"Rate limited. Waiting {wait:.1f}s (attempt {attempt + 1})")
time.sleep(wait)
elif block_type == "captcha":
# Switch to a new IP and wait
print(f"CAPTCHA detected. Rotating IP and waiting...")
time.sleep(random.uniform(10, 20))
else:
# Generic block: wait and retry
time.sleep(random.uniform(5, 15))
return None # All retries exhaustedSpójność geograficzna
Jednym z subtelnych, ale ważnych środków antydetekcji jest zapewnienie spójności geograficznej pomiędzy parametrami żądania:
- Jeśli Twój proxy IP jest w Stanach Zjednoczonych, set
gl=usorazhl=en - Dopasowanie nagłówka Accept- Language do docelowej lokalizacji
- Użyj łańcucha User- Agent dla kombinacji OS / przeglądarki wspólnej w tym kraju
- Ustaw odpowiedni czas żądania
ProxyHat Funkcja geocelowania pozwala na wybór proxy z konkretnych krajów i miast, co ułatwia utrzymanie tej spójności. Dowiedz się więcej o korzystaniu z aplikacji location- targeted w naszym przewodniku na temat skrobanie bez blokowania.
Node.js Anti-Block Implementacja
Oto równoważna strategia antyblokowa wdrożona w Node.js:
const axios = require('axios');
const cheerio = require('cheerio');
const { HttpsProxyAgent } = require('https-proxy-agent');
const 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 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0',
];
function getRandomUA() {
return USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)];
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function scrapeWithRetry(keyword, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const agent = new HttpsProxyAgent('http://USERNAME:PASSWORD@gate.proxyhat.com:8080');
try {
const { data, status } = await axios.get('https://www.google.com/search', {
params: { q: keyword, num: 10, hl: 'en', gl: 'us' },
headers: {
'User-Agent': getRandomUA(),
'Accept': 'text/html,application/xhtml+xml',
'Accept-Language': 'en-US,en;q=0.9',
},
httpsAgent: agent,
timeout: 15000,
validateStatus: () => true,
});
if (status === 429) {
const wait = Math.pow(2, attempt) * 5000 + Math.random() * 5000;
console.log(`Rate limited. Waiting ${(wait/1000).toFixed(1)}s`);
await sleep(wait);
continue;
}
if (data.toLowerCase().includes('captcha')) {
console.log('CAPTCHA detected. Rotating IP...');
await sleep(10000 + Math.random() * 10000);
continue;
}
return cheerio.load(data);
} catch (err) {
console.log(`Attempt ${attempt + 1} failed: ${err.message}`);
await sleep(5000 + Math.random() * 10000);
}
}
return null;
}Zaawansowane techniki
Randomizacja zapytań
Nie skracaj słów kluczowych w kolejności alfabetycznej lub sekwencyjnej. Ukryj listę słów kluczowych przed każdym uruchomieniem:
import random
keywords = ["proxy service", "web scraping", "serp tracking", "seo tools"]
random.shuffle(keywords)
# Now scrape in random order
for kw in keywords:
scrape_with_retry(kw)Parametry wyszukiwania Google
Użyj tych parametrów, aby uzyskać czyste, niezindywidualizowane wyniki:
| Parametr | Wartość | Cel |
|---|---|---|
pws | 0 | Wyłącz zindywidualizowane wyniki |
gl | Kod kraju | Ustaw kraj wyszukiwania |
hl | Kod języka | Ustaw język interfejsu |
num | 10- 100 | Wyniki na stronę |
filter | 0 | Wyłącz filtrowanie duplikatów |
nfpr | 1 | Wyłącz autokorektę |
Rozpowszechniony harmonogram
W celu monitorowania SERP w dużej skali, rozprowadzaj wnioski w czasie, aby uniknąć pęknięć. Zamiast drapania 10.000 słów kluczowych w ciągu jednej godziny, rozprzestrzeniać je na 8- 12 godzin z naturalnych krzywych ruchu (więcej wniosków w godzinach pracy, mniej w nocy).
Celem nie jest tylko unikanie bloków - jest to, aby Twoje scrating ruchu nie można odróżnić od normalnego zachowania wyszukiwania użytkownika. Każdy szczegół ma znaczenie.
Więcej na temat budowy niezawodnych, wielkoskalowych rurociągów, zobacz Kompletny przewodnik po proxy do skrobania stron internetowych oraz Rozwiązania do skrobania stron internetowych ProxyHat.






