Ir al contenido

Cómo utilizar selectores CSS para web scraping en Python

Los selectores de CSS proporcionan una forma poderosa de orientar y extraer contenido específico de páginas HTML. Esta guía detallada cubre todo lo que necesita saber para aprovechar los selectores de CSS para el web scraping en Python.

Introducción a los selectores de CSS

Los selectores CSS le permiten seleccionar elementos en una página web según su identificación, clase, nombre de etiqueta, atributos y más. Aquí hay unos ejemplos:

  • div - Seleccionar todo
    elementos
  • #container – Seleccionar elemento con id="contenedor"
  • .item – Seleccionar elementos con class="item"
  • a[href^="http"] – Seleccione etiquetas de anclaje con href que comiencen con http

Hay más de 50 tipos y combinaciones de selectores CSS diferentes disponibles. Esto incluye selectores de etiqueta, ID, clase, atributo, pseudoclase, posicional, de estado y léxico.

Algunos tipos de selectores de claves incluyen:

SelectorEjemploDescripción
Tipo de PropiedadaSelecciona todos los elementos de un tipo de etiqueta determinado
ID#containerSelecciona elemento con atributo de identificación específico
Clase.itemSelecciona elementos con un atributo de clase específico.
Atributoa[target]Seleccionar elementos con atributo específico
pseudo-clasea:hoverSeleccionar elementos en estado específico

Estos se pueden combinar de diferentes maneras para apuntar a elementos con mucha precisión. Por ejemplo:

div.content table.data tr.highlight > td

Que se descompone en:

  • div.content<div> elementos con clase="contenido"
  • table.data<table> elementos con class="data" dentro del <div>
  • tr.highlight<tr> elementos con class="highlight" dentro del <table>
  • > td<td> elementos que son hijos directos de la <tr>

Como puede ver, los selectores de CSS le permiten profundizar y especificar elementos en la jerarquía HTML con mucha precisión. Esto los hace invaluables para extraer datos específicos de páginas web.

Los estudios muestran que los identificadores y clases de CSS se utilizan en más del 90% de los sitios para permitir el estilo. Esta prevalencia también los hace excelentes para seleccionar contenido para extraer.

Usando selectores CSS en Python

Las bibliotecas populares de Python como BeautifulSoup y Parsel tienen soporte integrado para selectores de CSS:

BeautifulSoup

Para usar selectores CSS en BeautifulSoup, llame al select() método en un BeautifulSoup :

from bs4 import BeautifulSoup

soup = BeautifulSoup(html)
links = soup.select(‘a‘) # All anchor tags
first_link = soup.select_one(‘a‘) # First anchor tag
  • select() devuelve una lista de todos los elementos coincidentes.
  • select_one() devuelve solo la primera coincidencia.

parcela

La biblioteca Parsel proporciona una API similar:

from parsel import Selector

selector = Selector(html)
links = selector.css(‘a‘).getall() 
first_link = selector.css(‘a‘).get()
  • .css() ejecuta los selectores CSS
  • .getall() devuelve todos los partidos
  • .get() devuelve el primer partido

Parsel se utiliza internamente en el marco de raspado web Scrapy.

Comparando bibliotecas

Tanto BeautifulSoup como Parsel tienen una funcionalidad de selección de CSS casi idéntica. Parsel es un poco más rápido en los puntos de referencia, pero BeautifulSoup proporciona funciones adicionales como buscar y modificar el DOM.

Para la mayoría de los propósitos de scraping, su compatibilidad con el selector CSS es intercambiable.

Ejemplos de selectores CSS

Ahora veamos algunos ejemplos específicos del uso de selectores CSS para extraer datos:

Obtener elementos por nombre de etiqueta

Seleccione todos los hipervínculos en una página:

links = soup.select(‘a‘)

Esto coincidirá con cualquier <a> elementos de etiqueta de anclaje.

Seleccionar elemento por ID

Obtenga un formulario en una página con una identificación específica:

login_form = soup.select_one(‘#loginForm‘) 

La # El prefijo indica que debe coincidir con el atributo de identificación. Esto seleccionará el elemento con id="loginForm".

Los ID deben ser únicos dentro de una página, por lo que siempre devolverá un elemento.

Obtener elementos por nombre de clase

Seleccione todos los elementos de la página con una clase específica:

products = soup.select(‘.product-item‘)

La . El prefijo denota un selector de clase. Esto seleccionará todos los elementos con class="product-item".

Tenga en cuenta que las clases se pueden reutilizar, por lo que pueden coincidir con varios elementos.

Seleccionar por valor de atributo

Extraiga campos de entrada según su atributo de tipo:

text_inputs = soup.select(‘input[type="text"]‘)

La [attribute="value"] La sintaxis le permite hacer coincidencias por valores de atributos específicos.

Combinar múltiples selectores

Seleccione anclajes dentro de un div de barra lateral específico:

sidebar_links = soup.select(‘div.sidebar a.highlight‘)

Esto coincidirá <a> elementos con class="highlight" dentro <div class="sidebar">.

Se pueden combinar varios selectores separándolos con un espacio que selecciona elementos descendientes.

Raspado de datos con selectores CSS

Una vez que haya extraído los elementos, los selectores CSS se pueden utilizar para extraer datos:

for product in soup.select(‘.product‘):
  name = product.select_one(‘.product-name‘).text
  price = product.select_one(‘.product-price‘).text
  print(name, price)

Esto recorre .product elementos, y raspa el .product-name y .product-price valores dentro de cada bloque de producto.

La ventaja de los selectores CSS es que le permiten aislar los datos que desea del HTML circundante.

Ejemplo de raspado: cuadros de información de Wikipedia

Por ejemplo, considere raspar cuadros de información de Wikipedia:

url = ‘https://en.wikipedia.org/wiki/Abraham_Lincoln‘
soup = BeautifulSoup(requests.get(url).text)

infobox = soup.select_one(‘.infobox‘)

title = infobox.select_one(‘.fn‘).text
born = infobox.select_one(‘.bday‘).text
office = infobox.select_one(‘.label[style*=bold]‘).text

print(title) # Abraham Lincoln
print(born) # February 12, 1809
print(office) # 16th President of the United States

Esto aísla el contenido del cuadro de información usando .infobox class, luego extrae campos específicos usando selectores de etiquetas, clases y atributos anidados.

Como puede ver, encadenar diferentes tipos de selectores le permite concentrarse en los datos que necesita.

Extraer datos de una tabla

Los selectores también pueden ayudar a extraer datos tabulares:

url = ‘https://www.example.com/data.html‘ 

soup = BeautifulSoup(requests.get(url).text)
table = soup.select_one(‘table.data-table‘)

headers = [h.text for h in table.select(‘th‘)]
rows = []
for row in table.select(‘tr‘):
  cells = [d.text for d in row.select(‘td‘)]
  rows.append(dict(zip(headers, cells)))

print(rows)  

Esto extrae una tabla de datos, lee las etiquetas del encabezado, luego recorre las filas y crea un diccionario a partir de los pares de encabezado y celdas.

Los selectores de CSS permiten extraer datos estructurados fácilmente.

Limitaciones de los selectores CSS para scraping

Una desventaja de los selectores de CSS es que solo pueden analizar HTML estático y no funcionan con contenido cargado dinámicamente a través de JavaScript. La eliminación de sitios modernos requiere herramientas adicionales como Selenium o la automatización del navegador.

También proporcionan una capacidad limitada para recorrer y seleccionar elementos principales. Por lo tanto, el encadenamiento sólo puede profundizar en una jerarquía, no hacia arriba.

A pesar de esto, los selectores de CSS siguen siendo una herramienta esencial para el scraping debido a su ubicuidad, velocidad y conveniencia para la extracción de datos.

Encadenamiento de selectores CSS

El encadenamiento permite profundizar en los elementos descendientes:

rows = soup.select(‘div#content table.data tr‘)
for row in rows:
  name = row.select_one(‘td.name‘).text
  price = row.select_one(‘td.price‘).text 
  print(name, price)

Primeramente <tr> Se seleccionan filas, luego específicas. <td> Las células de cada fila se extraen mediante encadenamiento.

El encadenamiento de selectores en combinación permite extraer datos en relación con la estructura y el contenido circundantes.

Selectores CSS avanzados

También hay algunas capacidades de selección de CSS más avanzadas que vale la pena cubrir:

Comodines

La * El selector comodín coincide con cualquier elemento:

panels = soup.select(‘div.panel *‘) # All descendants

Selectores de atributos

Es posible una coincidencia de atributos más compleja:

input[type^="text"] # Type starts with "text"
a[href$=".pdf"] # Href ends with ".pdf" 
div[class*="head"] # Class contains "head"

Pseudo selectores

Selectores de estado especiales como :hover, :visited etc. Por ejemplo:

a:visited {color: purple}

El soporte varía según los analizadores. Algunos pseudo selectores como :contains() son extensiones personalizadas en lugar de CSS.

Selectores de hermanos

Objetivo basado en hermanos, por ejemplo, hermano adyacente p + ul encuentra <ul> inmediatamente despues <p>.

la Negación

:not(selector) excluye elementos coincidentes.

Estos selectores adicionales proporcionan un control aún más preciso del raspado.

Raspado de sitios interactivos

Si bien los selectores de CSS solo funcionan en HTML estático, hay formas de usarlos al extraer páginas interactivas con contenido generado por JavaScript:

Automatización del navegador

Herramientas como Selenium pueden hacer que un navegador represente JavaScript antes de analizarlo con selectores de CSS:

from selenium import webdriver

driver = webdriver.Chrome()
driver.get(url)

soup = BeautifulSoup(driver.page_source)
results = soup.select(‘#results .result‘)

Esto permite seleccionar elementos después de que JS se haya ejecutado.

Navegación sin cabeza

Scraping sin cabeza, herramientas como Puppeteer y Playwright brindan soporte para selectores de CSS:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
  browser = p.chromium.launch()
  page = browser.new_page()
  page.goto(url)

  html = page.content()
  soup = BeautifulSoup(html)

Se puede analizar el contenido de la página después de la representación de JavaScript.

Extensiones del navegador

Las extensiones de navegador como SelectorGadget eliminan los selectores de CSS analizando el tráfico de red y DOM.

Estos enfoques permiten utilizar selectores de CSS en sitios dinámicos. Los selectores todavía solo coinciden con HTML, pero se generan dinámicamente a través de JavaScript.

Limitaciones y desafíos

Si bien los selectores de CSS son omnipresentes y convenientes, tienen algunas limitaciones:

Raspado de sitios complejos

Los selectores luchan con algunas estructuras complejas del sitio:

  • Los marcos y los iframes requieren un análisis por separado.
  • Las cuadrículas y diseños avanzados pueden requerir selectores complejos.
  • Los widgets interactivos y las aplicaciones integradas requieren enfoques alternativos.

A menudo se necesita una combinación de selección de CSS y otra lógica de análisis.

Problemas de desempeño

Los selectores muy largos y complejos pueden volverse lentos. Se debe evitar anidar a más de 3 o 4 niveles de profundidad.

Se recomienda mantener los selectores individuales simples, con no más de 3 o 4 componentes. Encadene múltiples selectores simples en lugar de expresiones únicas complicadas.

Selectores frágiles

La orientación basada en atributos como clase e ID genera selectores frágiles que se rompen fácilmente si esos valores cambian en los rediseños del sitio.

Cuando sea posible, apunte a elementos basados ​​en el nombre, la posición y la jerarquía en lugar de atributos frágiles. O combine varios selectores como respaldo.

Límites de recorrido DOM

Los selectores de CSS solo pueden recorrer el árbol descendiente, no hasta los elementos principales.

Las expresiones XPath proporcionan un recorrido más flexible tanto hacia arriba como hacia abajo en un documento.

Soporte de pseudoselector

Pseudo selectores CSS clásicos como :visited y :hover tienen soporte limitado para varios navegadores en los analizadores. Selectores personalizados como :contains() no son estándar.

Confíe en pseudoclases simples como :first-child en lugar de pseudoselectores complejos.

Alternativas a los selectores CSS

Si bien son indispensables, los selectores de CSS no son el único juego disponible para analizar HTML:

XPath

XPath es un lenguaje de consulta para seleccionar nodos en documentos XML/HTML y proporciona una alternativa a CSS.

Pros:

  • Recorrido más potente de la estructura del documento.
  • Estándar robusto mantenido por el W3C.

Contras:

  • Sintaxis detallada y compleja.
  • El rendimiento puede ser más lento.

Regex

Las expresiones regulares pueden extraer patrones de texto:

Pros:

  • Combinación de patrones potente y flexible.

Contras:

  • Confuso al analizar HTML anidado.
  • No hay soporte integrado para recorrido.

En la práctica, una combinación de selectores de CSS, XPath y Regex a menudo proporciona las capacidades más sólidas para el web scraping a escala industrial.

Herramientas y bibliotecas

A continuación se muestran algunas herramientas esenciales para trabajar con selectores de CSS:

  • Dispositivo selector – Extensión del navegador para generar selectores.
  • Dramaturgo – Scraper sin cabeza con soporte para selector CSS.
  • Scrapy – Marco de web scraping utilizando selectores Parsel y CSS.
  • Titiritero – Raspado de Chrome sin cabeza.
  • BeautifulSoup – Analizador HTML de Python líder.

Estos proporcionan todo lo necesario para aprovechar los selectores de CSS para el web scraping de producción.

Conclusión

Los selectores CSS proporcionan un mecanismo versátil y ubicuo para extraer datos de páginas web. La prevalencia de identificadores y clases en HTML los hace perfectos para profundizar y extraer solo el contenido que necesita.

Dominar la variedad de tipos de selectores y combinarlos mediante encadenamiento y anidamiento permite apuntar con extrema precisión. Con el poder de las bibliotecas de Python como BeautifulSoup y Parsel, los selectores de CSS son una técnica esencial para cualquier web scraper.

Únase a la conversación

Su dirección de correo electrónico no será publicada. Las areas obligatorias están marcadas como requeridas *