Volver al blog

selectolax Web Scraping: Análisis HTML rápido en Python

Alex Johnson
Alex Johnson

Senior Web Scraping Engineer

23-Jul-2026

TL;DR:

  • selectolax analiza HTML con selectores CSS y lo hace rápido, porque envuelve el motor Lexbor basado en C en lugar de realizar un análisis puramente en Python.
  • Lo que selectolax no hace es obtener. No tiene cliente HTTP y no renderiza JavaScript; entrégale bytes y los analiza, nada más.
  • La diferencia se muestra en un script. Un GET simple en una página de demostración renderizada por JavaScript le da a selectolax 0 nodos de citas; la misma URL obtenida a través de la API de Raspado Universal de Scrapeless con js_render le da todas las 10.
  • El análisis es real en esta guía. Una ejecución en vivo obtuvo las 10 citas con autores y arreglos de etiquetas intactos del HTML renderizado, usando css y css_first.
  • Las dos capas están claramente separadas. Scrapeless obtiene y renderiza; selectolax convierte los bytes en registros. Ninguno de los dos interfiere en el trabajo del otro.
  • Libre para comenzar en el lado de obtención. Crea tu clave API de Scrapeless en app.scrapeless.com.

Qué es selectolax, y qué no es

selectolax es un analizador HTML de Python construido para velocidad. Vincula el motor Lexbor, una biblioteca en C que implementa el estándar HTML, por lo que analizar un documento y ejecutar selectores CSS sobre él ocurre en código compilado en lugar de en el intérprete. Para la extracción de alto volumen —miles de páginas, bucles ajustados— esa diferencia es la razón por la que las personas optan por él en lugar de analizadores más pesados.

Es un analizador y solo un analizador. selectolax no tiene cliente HTTP, no mantiene sesiones, y no ejecuta JavaScript. Dale una cadena o bytes y construirá un árbol que puedes consultar; pídeles que obtengan una URL y no hay un método para eso, por diseño. Así que cada configuración de "raspado web con selectolax" tiene dos capas: algo que obtiene HTML fiel, y selectolax que lo convierte en datos. Esta guía utiliza la API de Raspado Universal de Scrapeless para la primera capa, porque un cliente HTTP simple devuelve los bytes incorrectos en cualquier página que construya su contenido con JavaScript. Para un recorrido más amplio del lado de Python, el tutorial de raspado web en Python cubre el ecosistema que rodea esto.

Instalación

selectolax y requests son toda la cadena de herramientas. La versión contra la que se escribió esta guía es selectolax 0.4.11:

bash Copy
pip install "selectolax==0.4.11" requests

Mantén tu clave en el entorno, nunca en el código fuente:

bash Copy
export SCRAPELESS_API_KEY="sk_tu_clave_de_scrapeless"

Obtén HTML que vale la pena analizar

La calidad de análisis está limitada por la fidelidad de obtención, así que comienza por ahí. En una página renderizada por JavaScript, el documento que recibe un cliente HTTP simple no es el documento que ve un lector: el contenido llega solo después de que los scripts construyen el DOM, un ciclo de vida definido por la especificación de scripting HTML. Un script cuenta la diferencia a través de selectolax mismo:

python Copy
# fidelity.py — lo que selectolax ve: GET simple vs renderizado del lado del servidor
import os

import requests
from selectolax.lexbor import LexborHTMLParser

URL = "https://quotes.toscrape.com/js/"

plain = requests.get(URL, timeout=60).text
print("caracteres GET simples:", len(plain), "| nodos de citas:", len(LexborHTMLParser(plain).css("div.quote")))

resp = requests.post(
    "https://api.scrapeless.com/api/v2/unlocker/request",
    headers={"Content-Type": "application/json", "x-api-token": os.environ["SCRAPELESS_API_KEY"]},
    json={"actor": "unlocker.webunlocker", "input": {"url": URL, "js_render": True}},
    timeout=120,
)
resp.raise_for_status()
rendered = resp.json().get("data", "")
print("caracteres renderizados:", len(rendered), "| nodos de citas:", len(LexborHTMLParser(rendered).css("div.quote")))

La ejecución imprime 0 nodos de citas para la obtención simple y 10 para la renderizada:

text Copy
caracteres GET simples: 5806 | nodos de citas: 0
caracteres renderizados: 8940 | nodos de citas: 10

El renderizado, desbloqueo y enrutamiento de proxy ocurre todo del lado del servidor en ese único POST — la API de Raspado Universal es la capa de obtención, y los bytes renderizados son lo que selectolax debería analizar.

Analízalo con selectolax

Con HTML real en mano, selectolax hace la extracción. css devuelve cada nodo que coincide con un selector; css_first devuelve el primero, así que puedes sacar un campo de cada registro. Los selectores siguen la especificación de selectores de W3C, la misma sintaxis que ya usas en CSS:

python Copy
# extract.py — obtén la página renderizada, luego extrae registros con selectolax
import os

import requests
from selectolax.lexbor import LexborHTMLParser

resp = requests.post(
    "https://api.scrapeless.com/api/v2/unlocker/request",

headers={"Content-Type": "application/json", "x-api-token": os.environ["SCRAPELESS_API_KEY"]},
json={"actor": "unlocker.webunlocker", "input": {"url": "https://quotes.toscrape.com/js/", "js_render": True}},
timeout=120,
)
resp.raise_for_status()
tree = LexborHTMLParser(resp.json().get("data", ""))

records = []
for quote in tree.css("div.quote"):
records.append({
"text": quote.css_first("span.text").text(),
"author": quote.css_first("small.author").text(),
"tags": [tag.text() for tag in quote.css("a.tag")],
})

print("registros:", len(records))
print("primer autor:", records[0]["author"])
print("primeras etiquetas:", records[0]["tags"])

Copy
La ejecución en vivo devolvió todos los 10 registros, con el autor y el arreglo de etiquetas intactos en el primero:

```text
registros: 10
primer autor: Albert Einstein
primeras etiquetas: ['cambio', 'profundas-reflexiones', 'pensamiento', 'mundo']

Ese es el scraper completo: un POST para obtener y renderizar, un árbol para consultar. text() devuelve el contenido de texto de un nodo, y construir una lista de diccionarios por registro es el patrón que se escala a cualquier bloque repetido en una página.

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

Patrones avanzados

  • Usa LexborHTMLParser para velocidad, HTMLParser para el backend Modesto. selectolax envía ambos motores detrás de la misma API; Lexbor es el más nuevo, más rápido y el predeterminado correcto para volumen.
  • Prefiere css_first con un default. node.css_first("span.text", default=None) devuelve None en lugar de lanzar un error cuando falta un campo, lo cual evita que un bucle sobre registros desiguales se caiga en la única página que difiere.
  • Lee atributos con .attributes. Para enlaces e imágenes, node.attributes.get("href") extrae el atributo del nodo — los selectores encuentran el elemento, .attributes lee sus datos.
  • Obtén markdown cuando no necesites el árbol. Si solo deseas texto legible, la API de Scrapeless puede devolver contenido renderizado directamente; recurre a selectolax cuando necesites control a nivel de selector sobre campos estructurados.

Solución de problemas

  • Cero nodos de una página que puedes ver en un navegador. El contenido es renderizado por JavaScript y tu fetch devolvió el HTML pre-renderizado. Cuenta un selector conocido de la misma manera que lo hace el primer script; un árbol casi vacío es un problema de fetch, que se soluciona con js_render, no es un problema de selector.
  • AttributeError: 'NoneType' object has no attribute 'text'. Un css_first no encontró nada y llamaste a .text() en None. Pasa default=None y verifica antes de leer, o confirma que el selector coincide con el marcado renderizado.
  • El texto tiene espacio en blanco adicional. text() devuelve el texto bruto del nodo; llama a .strip() o pasa opciones deep=True/separator cuando un nodo anida hijos cuyos textos deseas unir.
  • La codificación parece incorrecta. Pasa los bytes de respuesta en lugar de una cadena mal decodificada; selectolax lee la codificación declarada del documento cuando le entregas bytes.

Conclusión

selectolax se gana su lugar como la capa de análisis que nunca toca la red: entrégale HTML fiel y devuelve registros rápidamente, con selectores CSS que ya conoces. La capa que decide si alguna de eso es posible es el fetch — el conteo de 0 versus 10 del primer script lo establece — y un POST renderizado por el servidor cierra la brecha. Conecta los dos y las diez citas de la página de demostración llegan como diccionarios limpios, etiquetas y todo.

Crea una cuenta gratuita de Scrapeless para obtener una clave de API, y la documentación para desarrolladores cubre los parámetros de unlocker.webunlocker. Consulta los precios de Scrapeless cuando planees un trabajo recurrente.

Preguntas frecuentes

P: ¿Puede selectolax extraer sitios web por sí mismo?

No. selectolax analiza HTML que ya tienes; no tiene cliente HTTP y no renderiza JavaScript. Combínalo con una capa de fetch — aquí la API de Scraping Universal de Scrapeless, que renderiza la página del lado del servidor — y selectolax se encarga de la extracción de los bytes devueltos.

P: ¿Por qué usar selectolax en lugar de BeautifulSoup?

Velocidad. selectolax envuelve el motor Lexbor basado en C, así que el análisis y las consultas de selectores se ejecutan en código compilado, lo cual es importante a alto volumen de páginas. La compensación es una superficie de características más pequeña; para extracción basada en selectores a través de muchas páginas, esa suele ser la compensación correcta.

P: ¿Cuál es la diferencia entre css y css_first?
css devuelve una lista de cada nodo que coincide con el selector; css_first devuelve solo la primera coincidencia (o un valor predeterminado que proporciones). Usa css para recorrer bloques repetidos como los resultados de búsqueda, y css_first para extraer un solo campo de cada bloque.

Q: ¿Maneja selectolax páginas renderizadas con JavaScript?

No por sí solo: nunca ejecuta scripts. Si el contenido se carga después del HTML inicial, una búsqueda sencilla le entrega a selectolax un árbol vacío. Obtén la página a través de la API de Scrapeless con js_render primero, luego analiza el HTML renderizado, como hace esta guía.

Q: ¿Es legal hacer scraping con selectolax?

El analizador no cambia las reglas de colección. Solo obtén páginas públicas, respeta los términos del sitio y las directivas de robots estandarizadas por el Protocolo de Exclusión de Robots, mantén los volúmenes limitados y maneja cualquier dato personal de acuerdo con las leyes que te sean aplicables.

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