Cómo raspar la Biblioteca de Anuncios de Facebook con el navegador Scrapeless Scraping.
Specialist in Anti-Bot Strategies
TL;DR:
- La Biblioteca de Anuncios de Facebook es una superficie pública — ver anuncios en ella no requiere inicio de sesión. Cualquiera puede abrir
facebook.com/ads/library, buscar un anunciante o palabra clave, y leer cada anuncio activo e inactivo que una Página está ejecutando, incluyendo el nombre del anunciante, el texto del anuncio y las fechas en que se mostró cada anuncio. - La página se renderiza completamente del lado del cliente, por lo que una solicitud HTTP simple devuelve un contenedor vacío. Las tarjetas de anuncios son pintadas por JavaScript después de la respuesta inicial, y la cuadrícula de resultados está detrás de un chequeo anti-bots, así que una simple
requests.getno ve ningún anuncio en absoluto. - Scrapeless Scraping Browser renderiza la página del lado de la nube y devuelve el DOM pintado. Conectándose a través del Protocolo de Herramientas de Desarrollo de Chrome con salida residencial de EE. UU. y una sesión calentada devuelve la cuadrícula de resultados completamente renderizada, que se puede analizar como cualquier página estática.
- Descubre cada anuncio desde el ancla de texto estable
Library ID:, no una clase CSS encriptada. Cada tarjeta de anuncio lleva una etiquetaLibrary ID: <dígitos>; escalar desde ese ancla hasta su contenedor de tarjeta única sobrevive al cambio de nombres de clase en React que rompe selectores frágiles. - Una búsqueda por palabra clave devolvió 27 tarjetas de anuncios en el primer renderizado y 104 después de desplazarse por la cuadrícula seis veces. La paginación aquí es un desplazamiento infinito: la cuadrícula agrega más tarjetas a medida que te desplazas, así que lees el DOM después de cada desplazamiento hasta que la cuenta deja de crecer.
- Gratis para comenzar. Nuevas cuentas de Scrapeless incluyen tiempo de ejecución gratuito de Scraping Browser — regístrate en app.scrapeless.com.
Introducción: lee los anuncios públicos que cualquier marca está ejecutando
La Biblioteca de Anuncios de Facebook es el archivo de transparencia pública de Meta de los anuncios que se ejecutan a través de Facebook e Instagram. Cada anuncio activo — y, para anuncios de temas sociales, electorales y políticos, también cada anuncio inactivo — está listado con el anunciante, la creatividad y las fechas en que se mostró. Los investigadores competitivos, los equipos de seguridad de marca y los analistas de anuncios lo leen para ver exactamente qué mensajes una Página está mostrando a los usuarios en este momento.
La fricción está en el renderizado, no en el acceso. Ver anuncios públicos no necesita ninguna cuenta, pero la página construye su cuadrícula de resultados completa en el navegador después de la primera respuesta, y la cuadrícula está protegida por defensas contra tráfico automatizado que un cliente HTTP simple activa de inmediato. Descarga la URL con requests y las tarjetas de anuncio simplemente no están en los bytes que recibes — son pintadas más tarde por JavaScript que nunca se ejecuta. El marcado que sí se renderiza se basa en nombres de clase encriptados y rotativos de React, por lo que un selector fijado a una cadena de clase se rompe en el próximo despliegue del front-end.
Esta guía construye la extracción en Python sobre Scrapeless Scraping Browser, un navegador en la nube que renderiza la página con salida residencial de EE. UU. y devuelve el DOM terminado. El patrón es el mismo ciclo de renderizar → descubrir → extraer → paginar que impulsa cualquier raspador, con un giro: los descubrimientos se anclan en el duradero texto Library ID: que cada tarjeta imprime, de modo que el análisis sobrevive el cambio de nombres de clase. La misma división de renderizado estático y dinámico, en JavaScript, se cubre en el tutorial de Cheerio y Puppeteer.
Lo Que Puedes Hacer Con Esto
- Rastrear la creatividad en vivo de un competidor. Extrae cada anuncio activo que una Página está ejecutando para ver los mensajes actuales, ofertas y destinos de aterrizaje.
- Construir un conjunto de datos de tendencias creativas. Recopila textos de anuncios a través de muchos anunciantes en una categoría y analiza el lenguaje, ganchos y formatos que aparecen con frecuencia.
- Monitorear el tiempo de las campañas. Lee la fecha de "Comenzó a ejecutarse" en anuncios activos y el rango de ejecución en los inactivos para mapear cuándo se lanzan y retiran las campañas.
- Auditar la presencia de la marca. Confirma qué anuncios se vinculan a una Página verificada y detecta suplantadores que ejecutan anuncios bajo un nombre similar.
- Alimentar un pipeline de inteligencia sobre anuncios. Convierte la cuadrícula de resultados renderizada en filas estructuradas — anunciante, ID de biblioteca, estado, fechas — que el análisis posterior o un modelo puede leer.
- Alcanza la cuadrícula que HTTP simple no puede. La Biblioteca de Anuncios se renderiza del lado del cliente detrás de un chequeo anti-bots, así que escálalo a un navegador en la nube y mantén el mismo código de análisis que usarías en una página estática.
Por Qué Scrapeless Scraping Browser
Scrapeless Scraping Browser es un navegador en la nube personalizado, diseñado para rastreadores web y agentes de IA, que ofrece detección anti-detección. Para la Biblioteca de Anuncios específicamente, trae:
- Renderizado de JavaScript del lado de la nube. La cuadrícula de resultados se pinta después de la respuesta inicial; el navegador en la nube ejecuta la página y devuelve un DOM que ya contiene las tarjetas de anuncios, por lo que BeautifulSoup lo analiza como HTML estático.
- Proxies residenciales en más de 195 países. La Biblioteca de Anuncios varía su contenido según el país del espectador, así que fijar la salida residencial de EE. UU. devuelve los mismos anuncios que vería un visitante de EE. UU.
- Anti-detección de huellas digitales. La página protege su cuadrícula detrás de un verificador de robots; el navegador en la nube presenta una superficie de navegador consistente y similar a la de un humano, de modo que la cuadrícula se muestra en lugar de un desafío.
- Una clave API para todo. El SDK de Python genera un
browser_ws_endpointal que te conectas con Playwright a través de CDP, y la misma clave cubre el tiempo de ejecución.
Obtén tu clave API en el plan gratuito en app.scrapeless.com.
Prerequisitos
- Python 3.10 o superior
- El SDK
scrapeless,playwrightybeautifulsoup4 - Una cuenta Scrapeless y clave API — regístrate en app.scrapeless.com
- Familiaridad básica con la terminal
Instalación
Instala el SDK, el cliente de protocolo y el analizador HTML:
bash
pip install scrapeless playwright beautifulsoup4
playwright install chromium
playwright install chromium descarga un cliente de protocolo local una vez; la renderización real aún se ejecuta en la nube de Scrapeless. El SDK scrapeless genera la sesión del navegador y beautifulsoup4 analiza el DOM devuelto. Exporta tu clave antes de ejecutar cualquier cosa: export SCRAPELESS_API_KEY=your_api_token_here.
Paso 1 — Renderiza la página de la Biblioteca de Anuncios y confirma que los anuncios están presentes
Una extracción comienza con una renderización limpia. La URL de la Biblioteca de Anuncios toma la búsqueda en parámetros de consulta — q para la palabra clave, country para la geografía del espectador, active_status y ad_type para los filtros. Conéctate al navegador en la nube, calienta la sesión en la página de inicio pública de Facebook primero para que la solicitud lleve una superficie de navegador establecida, luego carga la URL de búsqueda y cuenta las tarjetas de anuncios antes de escribir un solo selector de campo.
python
import re
from scrapeless import Scrapeless
from scrapeless.types import ICreateBrowser
from playwright.sync_api import sync_playwright
URL = ("https://www.facebook.com/ads/library/"
"?active_status=all&ad_type=all&country=US&q=nike")
LIB = re.compile(r"Library ID:\s*\d+")
client = Scrapeless() # lee SCRAPELESS_API_KEY del entorno
session = client.browser.create(ICreateBrowser(proxy_country="US", session_ttl=240))
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(session.browser_ws_endpoint)
ctx = browser.contexts[0] if browser.contexts else browser.new_context()
page = ctx.pages[0] if ctx.pages else ctx.new_page()
page.goto("https://www.facebook.com/", wait_until="domcontentloaded", timeout=60_000)
page.wait_for_timeout(3_000) # calienta la sesión en la página de inicio pública primero
page.goto(URL, wait_until="domcontentloaded", timeout=60_000)
page.wait_for_timeout(8_000) # deja que la cuadrícula de resultados se renderice del lado del cliente
html = page.content()
browser.close()
print("bytes html:", len(html), "| tarjetas de anuncios en la primera renderización:", len(LIB.findall(html)))
Esto imprime una línea como bytes html: 1796025 | tarjetas de anuncios en la primera renderización: 27 — aproximadamente 1.8 MB de HTML renderizado que lleva 27 tarjetas de anuncios en la primera pintura (el recuento de bytes varía de ejecución a ejecución a medida que se cargan diferentes creativos). El título de la página es Ad Library, y Facebook reescribe la URL para agregar sus propios valores predeterminados (search_type=keyword_unordered, media_type=all, un bloque sort_data). El wait_until="domcontentloaded" más un asentamiento fijo es deliberado: la Biblioteca de Anuncios transmite solicitudes de análisis y personalización que nunca se detienen, por lo que esperar a que la red esté inactiva se estancaría hasta el tiempo de espera. Calentar en la página de inicio primero es lo que logra que la cuadrícula se renderice en lugar de un desafío anti-bots.
Paso 2 — Descubre cada anuncio desde un ancla estable, luego extrae sus campos
Los nombres de clase de React de la cuadrícula de resultados están hasheados y rotan entre implementaciones, así que un selector como div.x1lliihq es una responsabilidad. La señal duradera es el texto que imprime cada tarjeta: Library ID: <dígitos>. Descubrimiento de ancla en esa etiqueta, sube al ancestro más grande que aún envuelve exactamente un ID de biblioteca — ese contenedor es una tarjeta de anuncio — luego lee los campos a partir del texto y enlaces dentro de él.
python
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, "html.parser") # html del Paso 1
def single_card(node):
# Ancestro más grande cuyo subárbol aún contiene exactamente un "Library ID:".
best, n = node.parent, node.parent
while n is not None and len(LIB.findall(n.get_text(" ", strip=True))) == 1:
best, n = n, n.parent
return best
def fields(card):
txt = card.get_text("\n", strip=True)
lib = re.search(r"Library ID:\s*(\d+)", txt)
status = "Activo" if re.search(r"\bActivo\b", txt) else (
"Inactivo" si "Inactivo" en txt más que None)
started = re.search(r"Empezó a ejecutarse el ([A-Z][a-z]+ \d{1,2}, \d{4})", txt)
ran = re.search(r"([A-Z][a-z]+ \d{1,2}, \d{4}) - ([A-Z][a-z]+ \d{1,2}, \d{4})", txt)
advertiser = None
for a in card.find_all("a", href=True):
if re.match(r"https://www\.facebook\.com/[^/?#]+/?$", a["href"]) and a.get_text(strip=True):
python
anunciante = a.get_text(strip=True)
break
return {
"library_id": lib.group(1) if lib else None,
"anunciante": anunciante,
"estado": estado,
"comenzó_a_correr": comenzado.group(1) if comenzado else None,
"rango_activo": list(ran.groups()) if ran else None,
}
visto, tarjetas = set(), []
for nodo in soup.find_all(string=LIB):
tarjeta = tarjeta_unica(nodo)
if id(tarjeta) not in visto:
visto.add(id(tarjeta))
tarjetas.append(tarjeta)
registros = [campos(c) for c in tarjetas]
print("registros de anuncios extraídos:", len(registros))
for r in registros[:4]:
print(r)
Esto extrae 27 registros. Los primeros imprimen como anunciantes reales y fechas — {'library_id': '1869276447125570', 'anunciante': 'Nike', 'estado': 'Activo', 'comenzó_a_correr': '17 de mar, 2026', 'rango_activo': None}. Nota las dos formas de fecha: un anuncio activo imprime Comenzó a correr en <fecha>, mientras que un anuncio inactivo imprime un rango de ejecución <inicio> - <fin>, así que el parser lee ambos y deja el otro campo None. El anunciante proviene del primer enlace que apunta a una URL de Página desnuda (facebook.com/<pagina>/), que es el lugar más estable donde aparece el nombre de la Página en la tarjeta.
Obtén tu clave API en el plan gratuito: app.scrapeless.com
Paso 3 — Cargar más anuncios desplazando la cuadrícula de resultados
La Biblioteca de Anuncios no pagina con números de página: anexa más tarjetas a medida que te desplazas. El patrón confiable es desplazar la cuadrícula, esperar a que se rendericen las nuevas tarjetas, volver a leer el DOM y repetir hasta que la cuenta de tarjetas deje de aumentar. Contar las ocurrencias de Library ID: después de cada desplazamiento te dice cuándo se ha agotado la cuadrícula para esa búsqueda.
python
sesion = client.browser.create(ICreateBrowser(proxy_country="US", session_ttl=240))
with sync_playwright() as p:
navegador = p.chromium.connect_over_cdp(sesion.browser_ws_endpoint)
ctx = navegador.contexts[0] if navegador.contexts else navegador.new_context()
pagina = ctx.pages[0] if ctx.pages else ctx.new_page()
pagina.goto("https://www.facebook.com/", wait_until="domcontentloaded", timeout=60_000)
pagina.wait_for_timeout(3_000)
pagina.goto(URL, wait_until="domcontentloaded", timeout=60_000)
pagina.wait_for_timeout(8_000)
def cuenta_tarjetas():
return len(LIB.findall(pagina.content()))
cuentas = [cuenta_tarjetas()]
for _ in range(6): # la cuadrícula carga más tarjetas al desplazarte
pagina.mouse.wheel(0, 6_000)
pagina.wait_for_timeout(2_500)
cuentas.append(cuenta_tarjetas())
navegador.close()
print("cuenta de tarjetas después de cada desplazamiento:", cuentas)
Esto imprime cuenta de tarjetas después de cada desplazamiento: [27, 37, 47, 66, 75, 85, 104] — la cuadrícula creció de 27 tarjetas en la primera representación a 104 después de seis desplazamientos. Cuando dos conteos consecutivos coinciden, la cuadrícula ha dejado de cargar para esa consulta y puedes dejar de desplazarte. Mantén el paso de desplazamiento modesto y el tiempo de espera lo suficientemente largo para que las nuevas tarjetas se dibujen, o leerás el conteo antes de que la cuadrícula se ponga al día.
Paso 4 — Escribir la salida estructurada
La lista registros del Paso 2 ya es una lista de diccionarios con claves consistentes, por lo que escribirla en CSV o JSON es cuestión de unas pocas líneas. Decide el esquema de antemano: las mismas claves en cada fila, así que un campo ausente se convierte en un None, nunca en un colapso.
python
import csv
import json
# registros es la lista de diccionarios construida en el Paso 2 (vuelve a ejecutar el parseo después del
# desplazamiento final en el Paso 3 para capturar cada tarjeta cargada).
nombres_campos = ["library_id", "anunciante", "estado", "comenzó_a_correr", "rango_activo"]
with open("facebook_ads.csv", "w", newline="", encoding="utf-8") as f:
escritor = csv.DictWriter(f, fieldnames=nombres_campos)
escritor.writeheader()
for fila in registros:
escritor.writerow({**fila, "rango_activo": json.dumps(fila["rango_activo"])})
with open("facebook_ads.json", "w", encoding="utf-8") as f:
json.dump(registros, f, ensure_ascii=False, indent=2)
print("escribió", len(registros), "filas en facebook_ads.csv y facebook_ads.json")
Ese es el bucle completo: renderiza la cuadrícula en el navegador en la nube, descubre cada tarjeta desde el ancla de Library ID:, extrae el anunciante y las fechas, desplaza para cargar más y almacena. Cambia los parámetros q y country en la URL para apuntarlo a cualquier anunciante, palabra clave o región que sirva la Biblioteca de Anuncios.
Manejo responsable de los datos publicitarios
La Biblioteca de Anuncios es una superficie pública de transparencia, y los anuncios en ella son publicados por marcas para que cualquiera los vea, pero los registros aún están relacionados con anunciantes identificables, así que recógelos con cuidado:
- Mantente en la superficie pública. Todo en esta guía lee la misma cuadrícula de resultados anónimos, sin inicio de sesión, que cualquier visitante ve. No autentiques para acceder a vistas restringidas o extraer nada que la página pública no muestre.
- Recoge datos de anuncios y anunciantes, no datos personales. Los campos útiles aquí son la Página del anunciante, el creativo y las fechas de ejecución. Evita recopilar nombres de comentaristas, reacciones o cualquier información personal relacionada con un anuncio.
- Minimiza y mantente en el propósito. Obtén solo los campos que necesita tu análisis y no más, y reténlos solo durante el tiempo que la necesidad de uso requiera.
- Respeta los términos y límites de tasa de la plataforma. Cumple con los Términos de Servicio de Meta y el Protocolo de Exclusión de Robots, y mantén el volumen de solicitudes cortés; limita la salida y controla la concurrencia en lugar de saturar la red.
Para trabajos comerciales o sensibles a la conformidad, revisa los términos aplicables de la plataforma y consulta con un abogado antes de crear un pipeline recurrente.
Lo que recibirás
Después del análisis, cada tarjeta de anuncio se reduce a un único registro plano con un esquema consistente:
json
[
{
"library_id": "1869276447125570",
"advertiser": "Nike",
"status": "Activo",
"started_running": "17 de marzo de 2026",
"active_range": null
},
{
"library_id": "308819044896583",
"advertiser": "Nike",
"status": "Inactivo",
"started_running": null,
"active_range": ["15 de agosto de 2023", "24 de julio de 2025"]
}
]
// El esquema refleja exactamente lo que emite el análisis del Paso 2. Los valores de los campos son ejemplos ilustrativos.
Algunas cosas que puedes esperar en la práctica:
- El conteo de tarjetas varía entre ejecuciones. La misma consulta puede devolver un número ligeramente diferente de tarjetas dependiendo de qué anuncios estén activos y cuánto se haya cargado la red; trata el conteo como una instantánea, no como un total fijo.
- Dos formas de fecha, un esquema. Los anuncios activos tienen una única fecha de "Empezó a ejecutarse en"; los anuncios inactivos tienen un rango de ejecución. El analizador completa el que esté presente y deja el otro como
Ninguno. - Ancla en el texto, vuelve a verificar el deslizamiento. La etiqueta
ID de Biblioteca:es mucho más duradera que las clases React hash, pero Meta aún cambia periódicamente el diseño de la tarjeta; vuelve a verificar los patrones de descubrimiento y campos cuando se altere el marcado. - Limita tu salida.
proxy_country="US"mantiene los anuncios devueltos consistentes con un espectador de EE. UU.; cambia el código de país para que coincida con la región que necesitas, ya que la Biblioteca de Anuncios varía los resultados por país.
Conclusión: escala tu pipeline de extracción de la Biblioteca de Anuncios
Leer la Biblioteca de Anuncios de Facebook se reduce a cuatro pasos: renderiza la cuadrícula de resultados en un navegador en la nube, descubre cada anuncio desde el ancla estable ID de Biblioteca:, extrae el anunciante y las fechas de ejecución, y desplázate para cargar más hasta que el conteo se estabilice. La única parte de HTTP simple, incluso con la correcta semántica HTTP, no puede — ejecutar la cuadrícula del lado del cliente detrás de la verificación anti-bot — escala de manera limpia a Scrapeless Scraping Browser, que renderiza la página y devuelve el DOM que tu analizador ya entiende.
A partir de aquí, escálalo como cada raspador de producción se escala: ancla selectores en el gancho más duradero y vuelve a verificarlos cuando el diseño cambie, limita la salida a EE. UU. para coincidir con la audiencia a la que van dirigidos los anuncios, trata los campos ausentes como anulables y mantiene la concurrencia cortés por host. Para la misma separación de renderizado en JavaScript, la guía de Cheerio y Puppeteer aborda la decisión estática frente a dinámica en Node.js, y la superficie del SDK y de la CLI están documentadas en docs.scrapeless.com. Compara opciones de tiempo de ejecución en la página de precios cuando estés listo para ejecutarlo a gran volumen.
¿Listo para construir tu pipeline de datos impulsada por IA?
Únete a nuestra comunidad para reclamar un plan gratuito y conectarte con desarrolladores que están construyendo pipelines de inteligencia publicitaria: Discord · Telegram.
Regístrate en app.scrapeless.com para obtener un tiempo de ejecución gratuito de Scraping Browser y adapta los patrones anteriores a los anunciantes, palabras clave y regiones que necesite tu investigación de la Biblioteca de Anuncios.
Preguntas Frecuentes
P: ¿Es legal raspar la Biblioteca de Anuncios de Facebook?
La Biblioteca de Anuncios es un archivo de transparencia pública, y los anuncios en ella son visibles públicamente sin inicio de sesión, lo que generalmente lo coloca en una base más firme que los datos con acceso restringido. Las reglas aún varían según la jurisdicción y los Términos de Servicio de Meta, así que revisa los términos de la plataforma, recopila datos de anunciantes y anuncios en lugar de información personal, y consulta con un abogado para uso comercial.
P: ¿Necesito iniciar sesión para leer la Biblioteca de Anuncios?
No. Los anuncios públicos en la Biblioteca de Anuncios se muestran para visitantes anónimos, y esta guía se refiere a esa misma superficie sin inicio de sesión. No te autentiques para acceder a vistas que la página pública no muestra.
P: ¿Necesito un proxy?
Sí. La Biblioteca de Anuncios varía sus resultados según el país del espectador y restringe la cuadrícula detrás de una verificación de bot, así que utiliza proxies residenciales y fija el país con proxy_country para que la página devuelva los anuncios que un visitante local vería. La sesión del Navegador de Scraping incluye esa salida.
P: La página muestra un desafío o una cuadrícula vacía en lugar de anuncios — ¿cómo obtengo una representación limpia?
Esa es la verificación anti-bot en la solicitud. Renderiza a través del Navegador de Scraping sin scrapear con salida residencial de EE. UU. fijada, y calienta la sesión cargando facebook.com primero en la misma sesión antes de navegar a la URL de la Biblioteca de Anuncios, para que la solicitud lleve una superficie de navegador establecida y humana cuando se cargue la cuadrícula.
P: Mis selectores dejaron de funcionar después de un cambio en el diseño — ¿qué hago ahora?
Los nombres de clase React de la Biblioteca de Anuncios están hashados y rotan, así que nunca te fijes en ellos. Ancla el descubrimiento en el texto ID de Biblioteca: que cada tarjeta imprime y lee los campos a partir de patrones de texto y enlaces de página sin formato. Cuando Meta cambie el diseño de la tarjeta, vuelve a comprobar esos patrones de texto en lugar de perseguir cadenas de clase.
P: ¿Cómo puedo navegar a través de más de la primera pantalla de anuncios?
La cuadrícula utiliza desplazamiento infinito, no números de página. Desplaza la página, espera a que se pinten las nuevas tarjetas, vuelve a leer el DOM y repite hasta que el conteo de ID de Biblioteca: deje de crecer — en una única ejecución subió de 27 tarjetas a 104 en seis desplazamientos.
P: ¿Cuántas búsquedas puedo realizar en paralelo?
Mantén la concurrencia moderada — alrededor de tres sesiones por host es un techo razonable — para que permanezcas dentro de tasas de solicitud adecuadas. Las sesiones de navegador en la nube son más pesadas que las solicitudes HTTP, así que limítalas más estrictamente de lo que harías con una búsqueda estática.
P: ¿Puedo hacer esto sin un agente de IA?
Sí. El flujo de Python y SDK mencionado anteriormente se ejecuta de extremo a extremo por sí solo. Un agente es una capa de conveniencia encima; el bucle de renderizar → descubrir → extraer → desplazarse es código simple que puedes programar directamente.
En Scrapeless, solo accedemos a datos disponibles públicamente y cumplimos estrictamente con las leyes, regulaciones y políticas de privacidad del sitio web aplicables. El contenido de este blog es sólo para fines de demostración y no implica ninguna actividad ilegal o infractora. No ofrecemos garantías y renunciamos a toda responsabilidad por el uso de la información de este blog o enlaces de terceros. Antes de realizar cualquier actividad de scraping, consulte a su asesor legal y revise los términos de servicio del sitio web de destino u obtenga los permisos necesarios.



