Volver al blog
Casos de uso

SEO Monitoring with Cloud Browsers: SERP Tracking Guide

How to build automated SEO monitoring for search rankings, SERP features, and competitor tracking using cloud browsers.

Introduction

Search Engine Results Pages (SERPs) vary by location, device, personalization, and time. Accurate SEO monitoring requires checking rankings from multiple geographic locations with real browser environments. Cloud browsers enable this by providing authentic sessions from any location.

Why Browser-Based SERP Monitoring

Personalization-Free Results

Search engines personalize results based on browsing history, logged-in status, and previous searches. Cloud browsers start with a clean session, providing baseline rankings without personalization:

const browser = await puppeteer.connect({
  browserWSEndpoint:
    `wss://bots.win/ws?apiKey=YOUR_API_KEY&proxy=${encodeURIComponent(proxy)}`,
});

const page = await browser.newPage();
// Clean session - no history, no personalization
await page.goto('https://www.google.com/search?q=' + encodeURIComponent(keyword));

JavaScript-Rendered SERPs

Modern SERPs include JavaScript-rendered features (carousels, knowledge panels, People Also Ask). HTTP-based scrapers miss these elements.

Local Pack and Map Results

Local search results require both geographic IP and proper locale settings:

// US local search
const browser = await puppeteer.connect({
  browserWSEndpoint:
    'wss://bots.win/ws?apiKey=YOUR_API_KEY&proxy=socks5h://user:pass@chicago:1080',
});

const page = await browser.newPage();
await page.goto('https://www.google.com/search?q=pizza+near+me&gl=us&hl=en');

SERP Data Extraction

Organic Results

async function extractOrganicResults(page) {
  return page.evaluate(() => {
    const results = [];
    const items = document.querySelectorAll('#search .g');

    items.forEach((item, index) => {
      const titleEl = item.querySelector('h3');
      const linkEl = item.querySelector('a[href]');
      const snippetEl = item.querySelector('.VwiC3b, [data-sncf]');

      if (titleEl && linkEl) {
        results.push({
          position: index + 1,
          title: titleEl.textContent,
          url: linkEl.href,
          snippet: snippetEl?.textContent || '',
        });
      }
    });

    return results;
  });
}

SERP Features

Track featured snippets, knowledge panels, and other special results:

async function extractSerpFeatures(page) {
  return page.evaluate(() => {
    const features = {};

    // Featured snippet
    const featuredSnippet = document.querySelector('.xpdopen, [data-attrid="wa:/description"]');
    if (featuredSnippet) {
      features.featuredSnippet = {
        text: featuredSnippet.textContent.substring(0, 500),
        present: true,
      };
    }

    // Knowledge panel
    const knowledgePanel = document.querySelector('.kp-wholepage, .knowledge-panel');
    if (knowledgePanel) {
      features.knowledgePanel = {
        title: knowledgePanel.querySelector('h2')?.textContent,
        present: true,
      };
    }

    // People Also Ask
    const paa = document.querySelectorAll('[data-sgrd] .related-question-pair');
    if (paa.length > 0) {
      features.peopleAlsoAsk = Array.from(paa).map(q => q.textContent);
    }

    // Local pack
    const localPack = document.querySelector('.VkpGBb');
    if (localPack) {
      features.localPack = { present: true };
    }

    return features;
  });
}

Multi-Location Monitoring

const locations = [
  { city: 'New York', proxy: 'socks5h://user:pass@ny:1080', gl: 'us' },
  { city: 'London', proxy: 'socks5h://user:pass@london:1080', gl: 'uk' },
  { city: 'Berlin', proxy: 'socks5h://user:pass@berlin:1080', gl: 'de' },
  { city: 'Tokyo', proxy: 'socks5h://user:pass@tokyo:1080', gl: 'jp' },
];

async function checkRankings(keyword, targetDomain) {
  const results = [];

  for (const location of locations) {
    const browser = await puppeteer.connect({
      browserWSEndpoint:
        `wss://bots.win/ws?apiKey=YOUR_API_KEY&proxy=${encodeURIComponent(location.proxy)}`,
    });

    const page = await browser.newPage();
    const searchUrl = `https://www.google.com/search?q=${encodeURIComponent(keyword)}&gl=${location.gl}&num=100`;
    await page.goto(searchUrl, { waitUntil: 'networkidle2' });

    const organicResults = await extractOrganicResults(page);
    const targetResult = organicResults.find(r => r.url.includes(targetDomain));

    results.push({
      location: location.city,
      keyword,
      position: targetResult?.position || 'not found',
      totalResults: organicResults.length,
    });

    await browser.close();
  }

  return results;
}

Best Practices

  1. Use location-appropriate proxies for accurate local rankings
  2. Run checks from clean sessions to avoid personalization
  3. Monitor SERP features in addition to organic positions
  4. Track competitors alongside your own rankings
  5. Schedule regular checks but respect rate limits
  6. Store raw HTML for post-analysis and debugging
  7. Compare across devices since mobile and desktop SERPs differ
#seo#serp#monitoring#search