Volver al blog

De Sitemaps a Enlaces Renderizados: La Pilas de 6 Métodos para el Descubrimiento Completo de URL del Sitio

Ava Wilson
Ava Wilson

Expert in Web Scraping Technologies

03-Jun-2026

Conclusiones Clave:

  • No hay un solo comando que liste cada página. Un inventario completo de URL proviene de métodos superpuestos: el operador de búsqueda site: para una estimación rápida, sitemap.xml y el índice del sitemap para lo que el sitio publica, las directrices del Sitemap en robots.txt para los puntos de entrada, un rastreador SEO o un rastreador de Python para lo que está realmente enlazado, y un navegador en la nube para enlaces del lado del cliente que solo aparecen después de que se ejecuta JavaScript.
  • Los sitemaps son la fuente autorizada más rápida — cuando existen y se mantienen actualizados. Un único requests.get("/sitemap.xml") más un recorrido recursivo de cualquier índice de sitemap puede devolver cientos de URL en una sola pasada.
  • Un rastreador en amplitud encuentra lo que los sitemaps omiten. Los sitemaps son curados por los autores y, a menudo, están desactualizados; un recorrido BFS de los enlaces internos <a href> descubre páginas huérfanas, contenido enlazado en profundidad, y cualquier cosa que el sitemap olvidó. El rastreador en esta guía respeta las reglas Disallow de robots.txt en cada URL antes de recuperarla.
  • Los enlaces renderizados por JavaScript necesitan un navegador real. Las aplicaciones de una sola página y los catálogos de desplazamiento infinito pintan sus enlaces internos del lado del cliente, por lo que una simple solicitud HTTP devuelve un shell casi vacío. Scrapeless Scraping Browser renderiza la página en un navegador en la nube, luego recoges los anclajes del DOM hidratado — con la salida residencial de EE. UU. fijada en la sesión.
  • Gratis para comenzar. Las nuevas cuentas de Scrapeless incluyen ejecución gratuita del navegador de scraping — regístrate en app.scrapeless.com.

Introducción: por qué un inventario completo de URL es más difícil de lo que parece

Conocer cada página en un sitio web es la base para mucho trabajo: una auditoría técnica de SEO, una migración de contenido, una búsqueda de enlaces rotos, un pipeline de monitoreo de precios que necesita cada URL de producto, o un trabajo de ingestión de LLM que quiere todo el corpus de texto. El problema es que ningún sitio te entrega una lista garantizada y completa. La página de inicio enlaza con la mayoría de las secciones, el sitemap publica algunas páginas, y las páginas huérfanas — alcanzables por enlace directo pero no enlazadas desde la navegación — se escapan de ambas.

Las opciones existentes cubren cada una un segmento. El operador de Google site: da una estimación pública rápida pero limita los resultados y refleja solo lo que está indexado. Un sitemap.xml es autoritativo para lo que el editor eligió declarar, pero se desactualiza y omite páginas que el CMS nunca registró. Un rastreador que sigue enlaces encuentra el gráfico enlazado, pero un rastreador HTTP simple devuelve un shell vacío en páginas pesadas en JavaScript donde la navegación se renderiza en el lado del cliente.

Esta guía recorre seis métodos en orden de costo y completitud — primero los más baratos y rápidos, y al final los más completos y renderizados. Los ejemplos de Python utilizan requests y la biblioteca estándar para los niveles estáticos, y un navegador en la nube a través de Scrapeless Scraping Browser para el nivel de JavaScript, de modo que los enlaces del lado del cliente se vuelvan descubiertos. Fija la salida de EE. UU., renderiza la página, recoge los anclajes. Los enlaces cruzados a guías hermanas se encuentran al final.


Lo Que Puedes Hacer Con Esto

  • Auditorías técnicas de SEO. Enumera cada URL indexable, luego difiere el rastreo contra el sitemap para sacar a la luz páginas huérfanas y páginas que el sitemap olvidó.
  • Migraciones de contenido. Construye la lista completa de URLs fuente antes de un replatform para que nada arroje un error 404 después del corte, y mapea las rutas antiguas a las nuevas.
  • Búsquedas de enlaces rotos. Recorre el gráfico de enlaces internos, registra cada destino y señala aquellos que devuelven un estado diferente a 200.
  • Monitoreo de precios y catálogos. Descubre cada URL de producto en un minorista — incluyendo aquellas renderizadas por JavaScript — y aliméntalas en un pipeline de extracción posterior.
  • Ingesta del corpus de LLM. Produce el conjunto completo de URLs de contenido para que un trabajo de extracción de texto pueda obtener todo el corpus público sin perder artículos enlazados en profundidad.
  • Mapeo de contenido competitivo. Inventaria la estructura pública de secciones de un competidor desde sitemaps y gráficos de enlaces para dimensionar su huella de contenido.

Por Qué Scrapeless Scraping Browser

La mayor parte de esta guía funciona con la biblioteca estándar de Python y requests — los sitemaps y robots.txt son texto plano y XML, y un rastreador de enlaces estáticos no necesita nada más. Scrapeless Scraping Browser es un navegador en la nube personalizable, diseñado para rastreadores web y agentes de IA; es el nivel al que recurres cuando los enlaces que necesitas solo existen después de que se ejecute JavaScript. Para el descubrimiento de URL de todo el sitio específicamente, ofrece:

  • Renderización de JavaScript del lado de la nube, así que los enlaces internos en una aplicación de una sola página, un catálogo de desplazamiento infinito, o una navegación de React/Vue/Next.js aparecen en el DOM que lees — no como un vacío <div id="root">.
  • Salida de proxy residencial de EE. UU., fijada por sesión, así que los sitios con restricción geográfica sirven la misma estructura de página que sirven a un visitante de EE. UU.
  • Fingerprinting anti-detección en cada sesión, de modo que la página renderizada coincide con lo que ve el tráfico orgánico en lugar de un perfil de automatización marcado.
  • Continuidad de sesión a través de una navegación de calentamiento y la página objetivo, por lo que una visita a la página de inicio que establece cookies se lleva a la página que realmente deseas enumerar.
  • Un único punto final, estándar CDP, por lo que Playwright (o cualquier cliente del Protocolo de Herramientas para Desarrolladores de Chrome) se conecta a través de WebSocket sin que un navegador local realice el renderizado.

Obtén tu clave API en el plan gratuito en app.scrapeless.com.


Requisitos previos

  • Python 3.10 o posterior.
  • Una cuenta de Scrapeless y clave API — regístrate en app.scrapeless.com.
  • pip install requests playwright y playwright install chromium (el Chromium local es solo el cliente del protocolo CDP; el renderizado se realiza en la nube de Scrapeless).
  • Familiaridad básica con la terminal y HTTP.

Método 1 — El operador de búsqueda site: de Google

La estimación inicial más rápida no necesita código. Escribe esto en Google:

Copy
site:example.com

Google devuelve las páginas que ha indexado para ese host, y el encabezado de resultados muestra un recuento aproximado. Acota para mapear la estructura de secciones:

  • site:example.com/blog — solo URLs bajo /blog.
  • site:example.com inurl:product — URLs indexadas cuyo camino contiene product.
  • site:example.com -inurl:tag — excluye un segmento de camino que no te interesa.

Para qué es bueno este método: una idea rápida de cómo es de grande el sitio y qué secciones existen. Para qué no es bueno: completitud. El operador site: refleja solo las páginas que Google ha decidido indexar, el recuento de resultados es una estimación en lugar de una cifra exacta, y el operador limita cuántos resultados puedes ver por página. Trátalo como una verificación de cordura en comparación con los métodos más exhaustivos a continuación: si tu mapa del sitio declara 5,000 URLs y site: muestra aproximadamente 200, esa diferencia es en sí misma un hallazgo.


Método 2 — Analizar sitemap.xml y el índice del mapa del sitio

Un mapa del sitio es la declaración del editor de sus URLs, servido como XML en una ruta convencional como /sitemap.xml. Es la única fuente autorizada más rápida cuando existe y se mantiene actualizada. Dos formas son relevantes:

  • Un mapa del sitio <urlset> lista las URLs de las páginas directamente, una <url><loc>…</loc></url> por página.
  • Un <sitemapindex> lista otros mapas del sitio — los sitios grandes dividen sus URLs en archivos hijos (pages_sitemap.xml, blog_sitemap.xml, etc.) y apuntan a ellos desde un índice. Caminas por el índice y luego caminas por cada hijo.

Este script de requests maneja ambas formas con una única función recursiva. Detecta la etiqueta raíz, recursiona en un índice de mapa del sitio y recopila las URLs de las páginas de cada <urlset>:

python Copy
import requests
import xml.etree.ElementTree as ET
from urllib.parse import urljoin

SM_NS = "{http://www.sitemaps.org/schemas/sitemap/0.9}"
HEADERS = {"User-Agent": "Mozilla/5.0 (sitemap-discovery)"}

def walk_sitemap(url, seen=None):
    """Devuelve cada URL de página accesible desde un mapa del sitio o índice de mapa del sitio."""
    seen = seen if seen is not None else set()
    if url in seen:          # guardia contra un mapa del sitio que se referencia a sí mismo
        return []
    seen.add(url)

    resp = requests.get(url, headers=HEADERS, timeout=30)
    resp.raise_for_status()
    root = ET.fromstring(resp.content)
    tag = root.tag.split("}")[-1]   # quita el espacio de nombres, mantiene "sitemapindex" o "urlset"

    urls = []
    if tag == "sitemapindex":
        # Un índice apunta a mapas del sitio hijos — recursiona en cada uno.
        for sm in root.findall(f"{SM_NS}sitemap"):
            loc = sm.findtext(f"{SM_NS}loc")
            if loc:
                urls.extend(walk_sitemap(loc.strip(), seen))
    else:
        # Un urlset lista URLs de páginas directamente.
        for u in root.findall(f"{SM_NS}url"):
            loc = u.findtext(f"{SM_NS}loc")
            if loc:
                urls.append(loc.strip())
    return urls

if __name__ == "__main__":
    pages = walk_sitemap("https://example.com/sitemap.xml")
    print(f"Descubiertas {len(pages):,} URLs del árbol del mapa del sitio")
    for u in pages[:10]:
        print(" ", u)

Ejecutado contra un sitio cuyo /sitemap.xml es un índice de mapa del sitio que apunta a mapas del sitio hijos, la caminata recursiva devuelve la unión de cada mapa del sitio hijo en una sola pasada.

Algunas notas sobre los mapas del sitio en el mundo real:

  • La ruta es una convención, no una garantía. /sitemap.xml es la ubicación común, pero un sitio puede nombrarlo como desee y declarar la ruta real en robots.txt (Método 3). Siempre revisa robots.txt antes de asumir que el archivo no existe.
  • Existen mapas del sitio comprimidos. Algunos sitios sirven sitemap.xml.gz; requests no descomprime automáticamente un cuerpo .gz, por lo que debes descomprimirlo con el módulo gzip antes de analizarlo si te encuentras con uno.
  • Los sitemaps se vuelven obsoletos. Reflejan lo que el CMS registró en el momento de la generación. Las páginas añadidas desde la última construcción y las páginas huérfanas que el CMS nunca registró estarán faltando, que es exactamente por lo que existen los Métodos 5 y 6.

Método 3 — Leer las directrices del sitemap en robots.txt

Antes de rastrear cualquier cosa, obtiene /robots.txt. Sirve para dos propósitos en el descubrimiento de URL: a menudo declara la(s) ubicación(es) del sitemap con una o más líneas Sitemap:, y te dice qué rutas el sitio pide a los rastreadores que dejen en paz (Disallow:). Ambos importan — el primero alimenta el Método 2, el segundo es una obligación de cumplimiento que llevas al Método 5.

python Copy
import requests
from urllib.parse import urljoin

HEADERS = {"User-Agent": "Mozilla/5.0 (sitemap-discovery)"}

def sitemaps_from_robots(base_url):
    """Extraer cada directriz Sitemap: declarada en robots.txt."""
    resp = requests.get(urljoin(base_url, "/robots.txt"), headers=HEADERS, timeout=30)
    resp.raise_for_status()
    sitemaps = []
    for line in resp.text.splitlines():
        if line.lower().startswith("sitemap:"):
            sitemaps.append(line.split(":", 1)[1].strip())
    return sitemaps

if __name__ == "__main__":
    for sm in sitemaps_from_robots("https://example.com"):
        print("Sitemap declarado:", sm)

El robots.txt de un sitio a menudo declara una o más líneas Sitemap: — por ejemplo Sitemap: https://example.com/sitemap.xml. Alimenta eso directamente a walk_sitemap del Método 2 y tendrás el conjunto completo de URL declaradas del editor sin adivinar la ruta.

El patrón combinado es la columna vertebral del descubrimiento estático: leer robots.txt para encontrar el(los) sitemap(s) y las rutas no permitidas, luego recorrer cada sitemap declarado. Lo que esos dos devuelvan es tu inventario inicial autorizado. Todo lo que sigue es encontrar las páginas que faltan.

Obtén tu clave API en el plan gratuito: app.scrapeless.com


Método 4 — Rastreadores SEO (la opción sin código)

Si prefieres no escribir Python, un rastreador SEO de escritorio o en la nube realiza descubrimiento, mapeo de grafos de enlaces e informes en una herramienta. Los comunes — Screaming Frog SEO Spider, Sitebulb y los rastreadores de auditoría de sitios integrados en Ahrefs y Semrush — hacen el mismo trabajo básico: seed un URL inicial, seguir enlaces internos en amplitud, y producir una tabla de cada URL encontrada junto con el código de estado, título, profundidad y cuenta de enlaces entrantes.

Estas herramientas son la opción correcta cuando:

  • Deseas un informe visual y una exportación CSV sin mantener código.
  • Necesitas que se calculen por ti las columnas estándar de SEO (estado, canónico, capacidad de indexación, cadenas de redirección).
  • El sitio está mayormente en HTML renderizado por el servidor, lo cual los rastreadores de escritorio manejan nativamente.

Sus límites son importantes de conocer: los niveles gratuitos limitan la cantidad de URL (la edición gratuita de Screaming Frog se detiene en 500 URL), el renderizado de JavaScript es un modo opcional y más lento que no todos los niveles activan, y las herramientas de auditoría en la nube tienen un precio según el tamaño del proyecto. Para una auditoría única de un sitio pequeño, son difíciles de superar; para un pipeline repetible que alimenta otro sistema, los métodos programáticos a continuación te darán las URL como datos en lugar de un informe. Los próximos dos métodos son ese camino programático.


Método 5 — Un rastreador de enlaces internos BFS en Python

Cuando el sitemap está obsoleto o ausente, descubres páginas como lo hace un motor de búsqueda: comienza en la página de inicio, analiza cada <a href> interno, encola los que no has visto, y repite en amplitud hasta que la frontera esté vacía o alcanzas un límite de página. Esto encuentra páginas huérfanas y de enlace profundo que ningún sitemap declara.

Dos responsabilidades son innegociables en un rastreador de enlaces, y ambas están incorporadas en el código a continuación:

  1. Honrar robots.txt. Verifica can_fetch para cada URL antes de solicitarla y omite cualquier cosa que el sitio no permita. La urllib.robotparser de la biblioteca estándar lee y evalúa las reglas por ti.
  2. Permanecer en-host y deduplicar. Solo encola enlaces cuyo host coincide con el host inicial, elimina fragmentos de URL para que /page y /page#section cuenten una vez, y mantiene un conjunto seen para que un ciclo en el grafo de enlaces no repita para siempre.
python Copy
import requests
from collections import deque
from html.parser import HTMLParser
from urllib.parse import urljoin, urldefrag, urlparse
from urllib.robotparser import RobotFileParser

HEADERS = {"User-Agent": "Mozilla/5.0 (link-discovery)"}

class LinkParser(HTMLParser):
    """Recoge cada href de las etiquetas <a> en una página."""
    def __init__(self):
        super().__init__()
        self.links = []
    def handle_starttag(self, tag, attrs):
        if tag == "a":
            for key, value in attrs:
                if key == "href" and value:
                    self.links.append(value)

def load_robots(base_url):
    rp = RobotFileParser()
    rp.set_url(urljoin(base_url, "/robots.txt"))
python Copy
rp.read()           # analiza las reglas Disallow y cualquier retraso de rastreo
    return rp

def crawl(start_url, max_pages=200, user_agent="*"):
    """Recorrido en amplitud de enlaces internos, respetando robots.txt."""
    host = urlparse(start_url).netloc
    robots = load_robots(start_url)

    seen = {start_url}
    queue = deque([start_url])
    found, skipped = set(), []

    while queue and len(found) < max_pages:
        url = queue.popleft()

        # Puerta de cumplimiento: nunca obtener una ruta que el sitio desautorizó.
        if not robots.can_fetch(user_agent, url):
            skipped.append(url)
            continue

        try:
            resp = requests.get(url, headers=HEADERS, timeout=30)
            resp.raise_for_status()
        except requests.RequestException:
            # Una sola URL mala se registra fuera de banda, no se persigue en línea.
            continue
        if "text/html" not in resp.headers.get("Content-Type", ""):
            continue

        found.add(url)

        parser = LinkParser()
        parser.feed(resp.text)
        for href in parser.links:
            absolute = urldefrag(urljoin(url, href))[0]   # resolver + eliminar #fragmento
            if urlparse(absolute).netloc == host and absolute not in seen:
                seen.add(absolute)
                queue.append(absolute)

    return found, skipped

if __name__ == "__main__":
    pages, disallowed = crawl("https://example.com/", max_pages=200)
    print(f"Descubiertas {len(pages):,} páginas; saltadas {len(disallowed)} desautorizadas por robots.txt")

---

Una ejecución en vivo de este rastreador contra un catálogo de demostración estático descubrió 40 páginas con el límite establecido en 40 y cero URL saltadas, porque el `robots.txt` de ese sitio no desautorizaba nada. Apuntando a un sitio cuyo `robots.txt` desautoriza una ruta, el mismo rastreador se negó correctamente a la URL desautorizada y la registró en la lista de `saltadas` en lugar de obtenerla, cumpliendo en cada URL, no como un pensamiento posterior.

Cómo esto se compone con los métodos anteriores:

- **El rastreador encuentra lo que el sitemap omite;** el sitemap encuentra lo que el rastreador no puede alcanzar por enlace. Ejecuta ambos y toma la unión para el inventario más completo.
- **Los fallos se quedan fuera de banda.** Una URL que genera un error se elimina de esta pasada y el rastreo sigue adelante — una mala página nunca estanca toda la caminata. Reúne las URL eliminadas por separado para su revisión.
- **Limita la concurrencia por cortesía.** Un rastreador de un solo hilo como el anterior ya es gentil. Si lo paralelizas, mantenlo a **no más de 3 trabajadores por host**, y respeta cualquier `Crawl-delay` que declare el `robots.txt`.
- **El rastreador es solo HTML.** Los enlaces pintados por JavaScript después de la carga son invisibles para `requests`. Esa brecha es precisamente lo que el Método 6 cierra.

---

## Método 6 — Renderizar páginas pesadas en JavaScript con Scrapeless Scraping Browser

Un rastreador basado en `requests` lee cualquier bytes que el servidor envía. Para una aplicación de página única, un catálogo de desplazamiento infinito o una navegación de React/Vue/Next.js, esos bytes son un shell de aplicación — `<div id="root"></div>` más una etiqueta de script — y los enlaces internos se pintan del lado del cliente una vez que el paquete se ejecuta. HTTP simple no puede verlos; un navegador real puede.

Scrapeless Scraping Browser renderiza la página en un navegador en la nube y la expone a través del Protocolo de DevTools de Chrome. Te conectas con Playwright a través de un punto final de WebSocket, calientas la página de inicio para que la sesión lleve cookies, navegas al objetivo, luego recolectas los anclajes del DOM hidratado — la analogía de la página renderizada del paso de análisis de enlaces en el Método 5. La salida de EE. UU. está fijada en la sesión para que los sitios geo-restringidos sirvan su estructura estándar.

La conexión es una única URL de WebSocket construida a partir de tu clave API. Esta es la forma exacta de conexión:

```python
import os
from urllib.parse import urlencode
from playwright.sync_api import sync_playwright

def scraping_browser_url(proxy_country="US", session_ttl=240):
    params = urlencode({
        "token": os.environ["SCRAPELESS_API_KEY"],
        "sessionTTL": session_ttl,
        "proxyCountry": proxy_country,
    })
    return f"wss://browser.scrapeless.com/api/v2/browser?{params}"

Con el punto final en mano, renderiza el objetivo y cosecha sus enlaces internos:

python Copy
from urllib.parse import urljoin, urldefrag, urlparse

def discover_rendered_links(start_url, proxy_country="US"):
    """Renderiza una página pesada en JS en el navegador en la nube y recoge enlaces del mismo host."""
    host = urlparse(start_url).netloc
    homepage = f"{urlparse(start_url).scheme}://{host}/"

    with sync_playwright() as p:
        browser = p.chromium.connect_over_cdp(scraping_browser_url(proxy_country))
        context = browser.contexts[0] if browser.contexts else browser.new_context()
        page = context.pages[0] if context.pages else context.new_page()

        # Calienta la página de inicio primero para que la sesión lleve cookies, luego ve al objetivo.
        page.goto(homepage, wait_until="domcontentloaded", timeout=60_000)
        page.goto(start_url, wait_until="networkidle", timeout=60_000)

Leer hrefs del DOM hidratado, después de que se haya ejecutado el renderizado del lado del cliente.

Copy
    hrefs = page.eval_on_selector_all(
        "a[href]", "els => els.map(e => e.getAttribute('href'))"
    )
    browser.close()

links = set()
for href in hrefs:
    if not href:
        continue
    absolute = urldefrag(urljoin(start_url, href))[0]
    if urlparse(absolute).netloc == host:
        links.add(absolute)
return links

if name == "main":
found = discover_rendered_links("https://example.com/app/catalog")
print(f"Descubiertos {len(found):,} enlaces del lado del cliente después del renderizado")
for u in sorted(found)[:10]:
print(" ", u)


Lo que obtienes de vuelta

Cada método emite un conjunto de URLs absolutas; el inventario final es la unión deduplicada de todos ellos. Un registro combinado para un host se ve así:

json Copy
// El esquema refleja la unión de los cuatro métodos programáticos.
// Los recuentos son muestras ilustrativas, no un instantáneo congelado de ningún sitio hoy.
{
  "host": "example.com",
  "discovered_at_methods": ["sitemap", "robots", "bfs_crawl", "rendered"],
  "counts": {
    "from_sitemap": 226,
    "from_bfs_crawl": 40,
    "from_rendered": 18,
    "union_unique": 248
  },
  "sample_urls": [
    "https://example.com/",
    "https://example.com/blog",
    "https://example.com/blog/how-to-scrape-bbb-business-listings",
    "https://example.com/app/catalog?page=2"
  ],
  "skipped_by_robots": [
    "https://example.com/private/"
  ]
}

Algunas observaciones honestas sobre el descubrimiento de URLs de todo el sitio, que vale la pena conocer antes de ejecutar a gran escala:

  • La unión supera a cualquier fuente única. Los sitemaps declaran lo que el editor registró; el rastreo BFS encuentra huérfanos enlazados; el paso renderizado encuentra enlaces del lado del cliente. La cobertura es la unión de los tres menos las rutas no permitidas.
  • Deduplica en URLs normalizadas. Elimina fragmentos, decide si las barras finales y los parámetros de consulta ?utm_* son significativos para tu caso de uso, y normaliza antes de contar; de lo contrario, /page y /page/ inflarán el total.
  • Los sitemaps retrasan el contenido. Una página publicada después de la última construcción de sitemap solo aparece en los niveles de rastreo. Si un inventario completo importa, siempre ejecuta un rastreo junto con la lectura del sitemap.
  • Los enlaces del lado del cliente son invisibles para HTTP. Si un rastreo de requests de un sitio conocido grande devuelve solo un puñado de URLs, la navegación es casi con seguridad renderizada del lado del cliente — eleva ese host al Método 6.
  • Respeta la lista de desautorización de principio a fin. El arreglo skipped_by_robots no es una lista de tareas pendientes. Esas rutas se mantienen fuera del inventario.

Conclusión: construir un inventario completo de URLs

Encontrar cada página se reduce a cuatro movimientos programáticos superpuestos a una verificación manual: estimar el tamaño con site:, leer robots.txt para la ubicación del sitemap y las rutas no permitidas, caminar por el árbol del sitemap para las URLs declaradas, rastrear el gráfico de enlaces internos para los huérfanos, y renderizar los hosts pesados en JavaScript en un navegador en la nube para los enlaces del lado del cliente. Toma la unión, deduplica en URLs normalizadas, y ese es el inventario.
Para la capa de proxy que enruta el nivel renderizado, consulte ¿Qué es un proxy SSL?. La página del producto Scraping Browser y la página de precios cubren el nivel del navegador en la nube; la referencia completa del SDK se encuentra en docs.scrapeless.com. Fije la salida de EE. UU. en el nivel renderizado, caliente la página de inicio antes de la página objetivo, honre robots.txt en cada URL y trate la lista final como la unión de cada método.


¿Listo para construir tu canalización de datos impulsada por IA?

Únete a nuestra comunidad para reclamar un plan gratuito y conectarte con desarrolladores que construyen canalizaciones de descubrimiento de URL y rastreo: 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 sitios, mapas del sitio y regiones que la canalización necesita.


Preguntas Frecuentes

P: ¿Es legal rastrear un sitio web para encontrar todas sus páginas?

El descubrimiento en sí lee URLs visibles públicamente, pero la legalidad depende de qué accedas, desde dónde y bajo qué términos. Honra el robots.txt del sitio, revisa sus términos de servicio, evita áreas privadas o autenticadas, y consulta con un abogado para casos de alto riesgo. Scrapeless accede solo a datos disponibles públicamente.

P: ¿Mapa del sitio o rastreo: cuál ofrece la lista completa?

Ninguno por sí solo. Un mapa del sitio es la declaración del editor y a menudo está desactualizado o es parcial; un rastreo encuentra el gráfico vinculado pero omite páginas a las que ningún enlace está vinculado. El inventario completo es la unión de la exploración del mapa del sitio (Método 2) y el rastreo BFS (Método 5), con el nivel renderizado (Método 6) agregado para enlaces del lado del cliente.

P: ¿Por qué mi rastreador encuentra solo unas pocas páginas en un sitio grande?

El sitio casi seguramente renderiza su navegación del lado del cliente. Una simple búsqueda de requests devuelve el contenedor de la aplicación antes de que se ejecute JavaScript, por lo que no hay enlaces que seguir. Renderiza esos hosts con Scrapeless Scraping Browser (Método 6) y recoge los anclajes del DOM hidratado en su lugar.

P: ¿Necesito un proxy para el descubrimiento de URL?

Para la lectura de un mapa del sitio de un solo host y un rastreo estático y educado, a menudo no. Un proxy se justifica cuando el sitio geocierra contenido (necesitas salida de EE. UU. para ver la estructura de EE. UU.), cuando tu IP está limitada por tasa o cuando el nivel renderizado necesita salida residencial para coincidir con el tráfico orgánico. La conexión de Scrapeless en el Método 6 fija la salida con proxy_country="US".

P: ¿Cómo obtengo un renderizado limpio cuando una página sirve un desafío de acceso?

Fija la salida residencial de EE. UU. en la sesión y calienta la sesión: navega a la página de inicio del sitio primero en la misma sesión del navegador antes de la página objetivo, como lo hace el código del Método 6, para que se configuren las cookies y la página profunda se cargue en un contexto ya confiable. Un salto frío directo a una URL profunda tiene más probabilidades de generar un desafío.

P: ¿Qué sucede cuando el sitio cambia su HTML o estructura de enlaces?

El rastreador estático se basa en el elemento genérico <a href>, por lo que los cambios en el marcado rara vez lo rompen. Si has ajustado el selector del nivel renderizado a un contenedor específico, revísalo cuando cambie el marcado y amplíalo de nuevo a a[href] si el sitio reorganiza su navegación.

P: ¿Cómo evito sobrecargar el sitio mientras rastreo?

El rastreador de un solo hilo en el Método 5 ya es gentil. Si paralelizas, mantén la concurrencia a no más de 3 trabajadores por host, honra cualquier directiva de Crawl-delay en robots.txt y nunca programes una ruta que cubran las reglas de desautorización.

P: ¿Cómo desduplico el conjunto final de URL?

Normaliza antes de contar: quita #fragments, decide si una barra final y los parámetros de consulta de seguimiento (?utm_*) son significativos para tu caso de uso, y almacena URLs en un set indexado por la forma normalizada. Cada método ya devuelve un set; toma la unión de todos ellos y los duplicados se colapsan.

P: ¿Puedo descubrir URLs sin un agente de IA o ningún SDK?

Sí. Los Métodos 1–5 utilizan solo la biblioteca estándar de Python y requests. El Método 6 añade Playwright conectándose al endpoint de Scrapeless Scraping Browser a través de CDP: no se requiere marco de agente, solo la URL de WebSocket construida a partir de tu clave API.

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.

Artículos más populares

Catalogar