Casos de Uso

Recopilación de datos de investigación de redes sociales con manejo de CAPTCHA

Las plataformas de redes sociales utilizan CAPTCHA para protegerse contra la recopilación automatizada de datos. Los investigadores de mercado, los monitores de marcas y los investigadores académicos deben afrontar estos desafíos para recopilar datos sociales públicos para su análisis.


CAPTCHA en plataformas sociales

Plataforma Tipo CAPTCHA Cuando se activa Contexto
Instagram reCAPTCHA v2 Iniciar sesión, buscar, acceder al perfil Limitación de velocidad
facebook reCAPTCHA v2 Iniciar sesión, búsquedas repetidas Punto de control de seguridad
Twitter/X Cloudflare Turnstile Iniciar sesión, acceso API Prevención de robots
tiktok reCAPTCHA v3 Vistas de perfil, búsqueda Calidad del tráfico
LinkedIn Cloudflare Challenge Raspado de perfil Detección de robots
Reddit reCAPTCHA v2 Iniciar sesión, navegación intensa Prevención de abuso

Scraper de investigación de redes sociales

import requests
import time
import re

CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"


def solve_captcha(method, sitekey, pageurl, **kwargs):
    data = {
        "key": CAPTCHAAI_KEY,
        "method": method,
        "googlekey": sitekey,
        "pageurl": pageurl,
        "json": 1,
    }
    data.update(kwargs)
    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data=data)
    task_id = resp.json()["request"]

    for _ in range(60):
        time.sleep(5)
        result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": CAPTCHAAI_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        r = result.json()
        if r["request"] != "CAPCHA_NOT_READY":
            return r["request"]
    raise TimeoutError("Solve timeout")


class SocialMediaResearcher:
    def __init__(self, proxy=None):
        self.session = requests.Session()
        if proxy:
            self.session.proxies = {"http": proxy, "https": proxy}
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) "
            "AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 "
            "Mobile/15E148 Safari/604.1",
            "Accept-Language": "en-US,en;q=0.9",
        })

    def authenticate(self, login_url, credentials, sitekey):
        """Login with CAPTCHA handling."""
        # Load login page
        self.session.get(login_url)

        # Solve CAPTCHA
        token = solve_captcha("userrecaptcha", sitekey, login_url)

        # Submit login
        resp = self.session.post(login_url, data={
            **credentials,
            "g-recaptcha-response": token,
        })
        return resp.status_code == 200

    def collect_profiles(self, profile_urls):
        """Collect public profile data with CAPTCHA handling."""
        profiles = []

        for url in profile_urls:
            try:
                resp = self.session.get(url, timeout=30)

                # Handle CAPTCHA if triggered
                if self._has_captcha(resp.text):
                    resp = self._handle_captcha(resp.text, url)

                profiles.append({
                    "url": url,
                    "data": self._parse_profile(resp.text),
                    "status": "success",
                })
                time.sleep(5)  # Slow down between profiles

            except Exception as e:
                profiles.append({
                    "url": url,
                    "error": str(e),
                    "status": "failed",
                })

        return profiles

    def _has_captcha(self, html):
        return any(tag in html.lower() for tag in [
            'data-sitekey', 'g-recaptcha', 'cf-turnstile',
            'challenge-platform', 'captcha',
        ])

    def _handle_captcha(self, html, url):
        match = re.search(r'data-sitekey="([^"]+)"', html)
        if not match:
            return self.session.get(url)

        sitekey = match.group(1)

        if 'cf-turnstile' in html:
            token = solve_captcha("turnstile", sitekey, url)
            return self.session.post(url, data={"cf-turnstile-response": token})
        else:
            token = solve_captcha("userrecaptcha", sitekey, url)
            return self.session.post(url, data={"g-recaptcha-response": token})

    def _parse_profile(self, html):
        from bs4 import BeautifulSoup
        soup = BeautifulSoup(html, "html.parser")
        return {
            "name": self._safe_text(soup, "h1, .profile-name"),
            "bio": self._safe_text(soup, ".bio, .profile-bio"),
            "followers": self._safe_text(soup, "[data-followers], .followers"),
            "posts": self._safe_text(soup, "[data-posts], .posts-count"),
        }

    def _safe_text(self, soup, selector):
        el = soup.select_one(selector)
        return el.get_text(strip=True) if el else ""

Hashtag e investigación de tendencias

def research_hashtag(hashtag, platform_url, pages=5):
    """Collect posts for a specific hashtag."""
    researcher = SocialMediaResearcher(
        proxy="http://user:pass@mobile.proxy.com:5000"
    )

    all_posts = []
    for page in range(pages):
        url = f"{platform_url}/explore/tags/{hashtag}?page={page}"
        resp = researcher.session.get(url, timeout=30)

        if researcher._has_captcha(resp.text):
            resp = researcher._handle_captcha(resp.text, url)

        from bs4 import BeautifulSoup
        soup = BeautifulSoup(resp.text, "html.parser")
        posts = soup.select(".post-item, article")
        for post in posts:
            all_posts.append({
                "text": post.get_text(strip=True)[:500],
                "hashtag": hashtag,
                "page": page,
            })

        time.sleep(5)

    return all_posts

Monitoreo de menciones de marca

import json
from datetime import datetime


class BrandMonitor:
    def __init__(self, brand_name, keywords, proxy=None):
        self.brand = brand_name
        self.keywords = keywords
        self.researcher = SocialMediaResearcher(proxy=proxy)

    def daily_scan(self, platform_urls):
        """Run daily brand mention scan across platforms."""
        report = {
            "brand": self.brand,
            "date": datetime.now().isoformat(),
            "platforms": {},
        }

        for name, url in platform_urls.items():
            mentions = []
            for keyword in self.keywords:
                search_url = f"{url}/search?q={keyword}"
                try:
                    resp = self.researcher.session.get(search_url, timeout=30)

                    if self.researcher._has_captcha(resp.text):
                        resp = self.researcher._handle_captcha(
                            resp.text, search_url,
                        )

                    from bs4 import BeautifulSoup
                    soup = BeautifulSoup(resp.text, "html.parser")
                    results = soup.select(".search-result, .post")
                    mentions.append({
                        "keyword": keyword,
                        "count": len(results),
                    })
                    time.sleep(5)
                except Exception as e:
                    mentions.append({
                        "keyword": keyword,
                        "error": str(e),
                    })

            report["platforms"][name] = mentions

        return report


# Usage
monitor = BrandMonitor(
    brand_name="CaptchaAI",
    keywords=["captchaai", "captcha ai", "captcha solver"],
    proxy="http://user:pass@mobile.proxy.com:5000",
)
report = monitor.daily_scan({
    "twitter": "https://twitter-alternative.example.com",
    "reddit": "https://www.reddit.com",
})
print(json.dumps(report, indent=2))

Recomendaciones de proxy

Plataforma Mejor proxy ¿Por qué?
Instagram Móvil (4G) Espera tráfico de dispositivos móviles
facebook Residencial Marca las IP de DC de forma agresiva
Twitter/X Residencial Cloudflare bloquea los DC
tiktok Móvil (4G) Diseñado para acceso móvil
LinkedIn ISP residencial Espera IP de escritorio /corporate
Reddit Rotación residencial Límites de velocidad por IP

Pautas de limitación de tarifas

Plataforma Tasa de solicitud segura Duración de la sesión
Instagram 1 solicitud / 10 seg Máximo 5 min y luego descansar.
facebook 1 solicitud / 5 seg Máximo 10 minutos
Twitter/X 1 solicitud / 3 seg Máximo 15 minutos
tiktok 1 solicitud / 5 seg Máximo 5 minutos
LinkedIn 1 solicitud / 10 seg Máximo 5 minutos
Reddit 1 solicitud / 2 seg Máximo 30 minutos

Solución de problemas

Problema causa Solución
CAPTCHA cada solicitud IP marcada Rotar IP, usar red móvil autorizada
Cuenta bloqueada demasiadas acciones Reduzca la frecuencia, utilice varias cuentas
Página vacía devuelta Contenido detrás del inicio de sesión Autenticar primero
Bucle de desafío de Cloudflare La señales del navegador del navegador no coincide Utilice un navegador centrado en la privacidad o el diagnóstico controlado Puppeteer
Contenido diferente al del navegador Ubicación/cookie diferencias Haga coincidir el proxy geográfico con el público objetivo

Preguntas frecuentes

¿Se permite el scraping de redes sociales para investigaciones?

Es común la recopilación de datos públicos para investigaciones no comerciales. Los tribunales han dictaminado que la extracción de datos públicos no viola la CFAA. Sin embargo, respete siempre los Términos de servicio y los límites de tarifas de la plataforma.

¿Por qué las plataformas sociales me CAPTCHA tan rápido?

Las plataformas sociales invierten mucho en la detección de bots. Analizan patrones de navegación, frecuencia de solicitudes y señales del navegador del dispositivo. Utilice servidores red móvil autorizadaes y patrones de navegación realistas.

¿Debería utilizar una API en lugar de raspar?

Si la plataforma ofrece una API con los datos que necesitas, prefiérelo. Las API son más confiables y compatibles con los ToS. Utilice scraping + CaptchaAI solo para datos que no están disponibles a través de las API oficiales.


Guías relacionadas


Recopile datos de investigación de redes sociales de manera confiable:obtenga su clave CaptchaAIy manejar los CAPTCHA de la plataforma automáticamente.

Los comentarios están deshabilitados para este artículo.