Как парсить результаты поиска Google с прокси

Узнайте, как парсить SERP Google с помощью резидентских прокси. Полные примеры кода на Python, Node.js и Go для извлечения органических результатов, расширенных сниппетов и блоков «Похожие вопросы».

Как парсить результаты поиска Google с прокси

Зачем парсить результаты поиска Google?

Google обрабатывает более 8,5 миллиардов поисковых запросов в день, что делает его страницы выдачи (SERP) самым ценным источником конкурентной аналитики в интернете. Парсинг поисковой выдачи Google даёт доступ к органическим позициям, расширенным сниппетам, блокам «Похожие вопросы», локальной выдаче и рекламным объявлениям — всё в реальном времени.

Независимо от того, строите ли вы конвейер мониторинга SERP или выполняете разовое исследование ключевых слов, программный доступ к результатам Google позволяет автоматизировать рабочие процессы, которые вручную заняли бы часы. Типичные сценарии использования:

  • Отслеживание позиций по ключевым словам на разных рынках
  • Мониторинг видимости конкурентов по целевым запросам
  • Анализ распределения SERP-фич (сниппеты, изображения, видео)
  • Создание датасетов для SEO-исследований и контент-стратегии

Структура поисковой выдачи Google

Прежде чем писать парсер, необходимо разобраться в анатомии страницы результатов Google. Современная SERP может содержать более десятка различных типов результатов:

Тип результатаCSS / МаркерОписание
Органические результатыdiv#search .gСтандартные результаты с заголовком, URL и сниппетом
Расширенный сниппетdiv.xpdopenБлок ответа, отображаемый над органическими результатами
Похожие вопросыdiv.related-question-pairРаскрывающиеся вопросы в формате FAQ
Локальная выдачаdiv.VkpGBbКарта с 3 локальными предприятиями
Панель знанийdiv.kp-wholepageИнформационная боковая панель об объекте
Рекламные результатыdiv.uEierdПлатные объявления вверху и внизу страницы
Google часто меняет имена классов. Создавайте парсер с резервными селекторами и регулярно тестируйте его для надёжной работы.

Настройка среды для парсинга

Для надёжного парсинга Google необходимы три компонента: HTTP-клиент, прокси-соединение и HTML-парсер. Ниже — полные примеры на Python, Node.js и Go с использованием прокси ProxyHat.

Пример на Python

Сначала установите зависимости. Python SDK от ProxyHat упрощает настройку прокси.

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

С использованием Node SDK от ProxyHat и Cheerio для парсинга:

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

С использованием Go SDK от ProxyHat и 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)
    })
}

Парсинг различных типов SERP

Полноценный парсер должен обрабатывать не только органические результаты. Вот паттерны извлечения для наиболее ценных SERP-фич.

Расширенные сниппеты

# 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,
    }

Похожие вопросы

# 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))

Локальная выдача

# 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 "",
    })

Обработка блокировок и CAPTCHA от Google

Google активно защищается от автоматического парсинга. Без надлежащей прокси-инфраструктуры блокировки начнутся после нескольких десятков запросов. Основные механизмы защиты:

  • Ограничение частоты запросов: слишком много запросов с одного IP приводит к статусу 429
  • CAPTCHA: Google показывает reCAPTCHA при подозрении на автоматизацию
  • Репутация IP: IP-адреса дата-центров подвергаются более тщательной проверке, чем резидентские
  • Цифровой отпечаток браузера: отсутствующие или несогласованные заголовки вызывают подозрение

Подробные стратегии обхода обнаружения описаны в нашем руководстве по парсингу без блокировок и статье о том, как антибот-системы обнаруживают прокси.

Рекомендуемая стратегия использования прокси

Резидентские прокси необходимы для стабильного парсинга Google. Резидентские прокси ProxyHat предоставляют доступ к миллионам IP-адресов в 190+ локациях, обеспечивая автоматическую ротацию IP и геотаргетинг запросов. Ключевые рекомендации по настройке:

  • Меняйте IP при каждом запросе — не используйте один и тот же IP для последовательных запросов к Google
  • Добавляйте случайные задержки от 2 до 5 секунд между запросами
  • Устанавливайте User-Agent, соответствующий реальной версии браузера
  • Задавайте параметры hl и gl в соответствии с локацией вашего прокси

Обратитесь к документации ProxyHat для настройки аутентификации и управления сессиями.

Создание production-парсера

Переход от скрипта к production-пайплайну требует логики повторных попыток, структурированного вывода и мониторинга. Вот усовершенствованная версия парсера на 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)

Масштабирование парсера SERP

При мониторинге сотен или тысяч ключевых слов однопоточный парсинг слишком медленный. Рассмотрите следующие подходы к масштабированию:

  • Параллельные запросы: используйте asyncio (Python), worker-потоки (Node.js) или горутины (Go) для отправки нескольких запросов одновременно
  • Архитектура на основе очередей: помещайте ключевые слова в очередь (Redis, RabbitMQ) и обрабатывайте их несколькими воркерами
  • Управление пулом прокси: ProxyHat автоматически обеспечивает ротацию, но настройте привязку сессий в зависимости от ваших потребностей
  • Кэширование результатов: кэшируйте данные SERP, чтобы избежать повторных запросов одного и того же запроса в пределах временного окна

Подробное руководство по созданию масштабируемых систем парсинга читайте в нашем полном руководстве по прокси для веб-скрапинга.

Правовые и этические вопросы

Условия использования Google ограничивают автоматический доступ. При парсинге поисковой выдачи Google соблюдайте следующие рекомендации:

  • Соблюдайте ограничения частоты запросов и не перегружайте серверы Google
  • Используйте данные в законных деловых целях (SEO-мониторинг, исследование рынка)
  • Не распространяйте необработанные данные SERP в коммерческих целях без понимания применимого законодательства
  • Рассмотрите использование официальных API Google, если они удовлетворяют вашим потребностям
Всегда проверяйте местное законодательство в отношении веб-скрапинга и сбора данных перед развёртыванием парсера SERP в промышленных масштабах.

Готовы начать?

Доступ к более чем 50 млн резидентных IP в 148+ странах с AI-фильтрацией.

Смотреть ценыРезидентные прокси
← Вернуться в Блог