Volver al blog
Guías
Raluca Penciuc8 de julio de 202110 min de lectura

Guía completa de Web Scraping con Java

Guía completa de Web Scraping con Java

Qué es el web scraping

¿En qué consiste el web scraping? Muchos sitios web no ofrecen sus datos a través de API públicas, por lo que los programas de web scraping extraen los datos directamente del navegador. Es muy parecido a cuando una persona copia texto a mano, pero se hace en un abrir y cerrar de ojos.

Si tenemos en cuenta que una mejor inteligencia empresarial se traduce en mejores decisiones, este proceso resulta más valioso de lo que parece a primera vista. Los sitios web generan cada vez más contenido, por lo que ya no es recomendable realizar esta tarea de forma totalmente manual.

Quizá te estés preguntando: «¿Qué voy a hacer con estos datos?». Bueno, veamos algunos casos en los que el web scraping puede resultar realmente útil:

  • Generación de clientes potenciales: una empresa en funcionamiento necesita generar clientes potenciales para encontrar clientes.
  • Análisis de precios: la decisión de una empresa a la hora de fijar los precios y comercializar sus productos se basará en los precios de la competencia.
  • Aprendizaje automático: para que las soluciones basadas en la inteligencia artificial funcionen correctamente, los desarrolladores deben proporcionar datos de entrenamiento.

En este artículo, muy bien redactado, se ofrecen descripciones detalladas y ejemplos de uso adicionales sobre las ventajas del web scraping.

Aunque se comprenda cómo funciona el web scraping y cómo puede aumentar la eficacia de tu negocio, crear un scraper no es tan sencillo. Los sitios web disponen de muchos métodos para identificar a los bots e impedir que accedan a sus datos.

He aquí algunos ejemplos:

  • Pruebas de Turing públicas completamente automatizadas (CAPTCHA): Estos problemas lógicos son bastante fáciles de resolver para las personas, pero suponen un gran obstáculo para los rastreadores web.
  • Bloqueo de direcciones IP: si un sitio web detecta que se están realizando varias solicitudes desde la misma dirección IP, puede bloquear el acceso a dicho sitio web o ralentizar considerablemente la conexión.
  • Honeypots: enlaces invisibles que son visibles para los bots, pero no para los humanos; una vez que los bots caen en la trampa, el sitio web bloquea su dirección IP.
  • Bloqueo geográfico: es posible que el sitio web bloquee geográficamente determinados contenidos. Por ejemplo, es posible que se le muestre información específica de una región cuando solicite datos de otra zona (por ejemplo, precios de billetes de avión).

Superar todos estos obstáculos no es tarea fácil. De hecho, aunque no es demasiado difícil crear un bot aceptable, resulta tremendamente complicado desarrollar un excelente rastreador web. Por ello, las API para el rastreo web se han convertido en uno de los temas más candentes de la última década.

WebScrapingAPI recopila el contenido HTML de cualquier sitio web y se encarga automáticamente de los problemas que he mencionado anteriormente. Además, utilizamos Amazon Web Services, lo que garantiza velocidad y escalabilidad. ¿Te parece interesante? Empieza tu prueba gratuita de WebScrapingAPI y podrás realizar 5000 llamadas a la API durante los primeros 14 días.

Entender la Web

Para comprender la Web, es necesario conocer el Protocolo de Transferencia de Hipertexto (HTTP), que explica cómo se comunica un servidor con un cliente. Un mensaje contiene varios datos que describen al cliente y cómo gestiona los datos: el método, la versión HTTP y los encabezados.

Los rastreadores web utilizan el método GET para las solicitudes HTTP, lo que significa que recuperan datos del servidor. Algunas opciones avanzadas también incluyen los métodos POST y PUT. Para más información, puedes consultar aquí una lista detallada de los métodos HTTP.

En los encabezados HTTP se pueden encontrar varios detalles adicionales sobre las solicitudes y las respuestas. Puedes consultar la lista completa, pero los que son relevantes para el web scraping son:

  • User-Agent: indica la aplicación, el sistema operativo, el software y la versión; los rastreadores web se basan en este encabezado para que sus solicitudes parezcan más realistas.
  • Servidor: el nombre de dominio del servidor al que has accedido.
  • Referente: contiene el sitio de origen que visitó el usuario; por lo tanto, el contenido que se muestra puede variar, por lo que también hay que tener en cuenta este hecho.
  • Cookie: almacena información confidencial sobre una solicitud y el servidor (como tokens de autenticación).
  • Accept: garantiza que la respuesta del servidor sea de un tipo específico (por ejemplo: text/plain, application/json, etc.).

Introducción a Java

Java es un lenguaje de código abierto y orientado a objetos, lo que lo convierte en uno de los lenguajes de programación más populares. Han pasado casi dos décadas desde que conocimos Java, y este lenguaje de programación se ha vuelto cada vez más accesible.

Muchos de los cambios introducidos en Java han tenido como objetivo reducir las dependencias en la implementación del código. Por este motivo, muchos desarrolladores prefieren este lenguaje, pero también presenta otras ventajas:

  • Es de código abierto;
  • Ofrece una variedad de API;
  • Es multiplataforma, lo que ofrece una mayor versatilidad;
  • Cuenta con una documentación detallada y un soporte técnico fiable por parte de la comunidad.

Crea tu propio raspador web

Ahora podemos empezar a hablar de la extracción de datos. Lo primero es lo primero: necesitamos una página web que ofrezca información útil. Para este tutorial, hemos decidido extraer datos de esta página web que comparte recetas italianas.

Paso 1: Configurar el entorno

Para crear nuestro rastreador web en Java, primero debemos asegurarnos de que contamos con todos los requisitos previos:

  • Java 8: aunque Java 11 es la versión más reciente con soporte a largo plazo (LTS), Java 8 sigue siendo el estándar preferido para entornos de producción entre los desarrolladores.
  • Gradle: es una herramienta flexible de código abierto para la automatización de compilaciones que ofrece una amplia gama de funciones, incluida la gestión de dependencias (requiere Java 8 o superior);
  • Un IDE de Java: en esta guía utilizaremos IntelliJ IDEA, ya que facilita bastante la integración con Gradle.
  • HtmlUnit: permite simular acciones del navegador, como clics y el envío de formularios, durante el rastreo de páginas web, y es compatible con JavaScript.

Una vez realizada la instalación, debemos comprobar si hemos seguido correctamente las guías oficiales. Abre un terminal y ejecuta los siguientes comandos:

> java -version
> gradle -v

Esto debería mostrarte las versiones de Java y Gradle que tienes instaladas en tu ordenador:

Salida del terminal que muestra la versión de Java instalada y los detalles del entorno de ejecución de la JVM
Salida del terminal que muestra la información de la versión de Gradle junto con los detalles de la JVM y del sistema operativo

Si no aparece ningún error, entonces estamos listos para empezar.

Ahora vamos a crear un proyecto para poder empezar a escribir el código. Por suerte, JetBrains ofrece un tutorial muy bien elaborado sobre cómo dar los primeros pasos con IntelliJ y Gradle, para que no nos perdamos entre tantas configuraciones.

Asegúrate de que, una vez creado el proyecto, dejes que el IDE complete la primera compilación, ya que así obtendrás un árbol de archivos generado automáticamente.

Una vez hecho esto, abre el archivo «build.gradle» y añade la siguiente línea en el bloque «dependencies»:

implementación('net.sourceforge.htmlunit:htmlunit:2.51.0')

Esto instalará HtmlUnit en nuestro proyecto. No olvides pulsar el botón «Reload» (Actualizar) de la caja de herramientas de Gradle situada a la derecha para que desaparezcan todas las advertencias de «Not found» (No encontrado).

Barra de herramientas de Gradle en el IDE con una opción para recargar todos los proyectos de Gradle

Paso 2: Revisa la página que quieres extraer

¡Genial, sigamos! Ve a la página que quieras rastrear, haz clic con el botón derecho en cualquier lugar de la página y selecciona «Inspeccionar elemento». Se abrirá la consola de desarrollador, donde podrás ver el código HTML de la página web.

Página de recetas de Food Network abierta con Chrome DevTools para inspeccionar los elementos de la página

Paso 3: Envía una solicitud HTTP y extrae el código HTML

Ahora, para obtener ese código HTML en nuestro equipo local, tenemos que enviar una solicitud HTTP mediante HtmlUnit, que nos devolverá el documento. Volvamos al IDE y pongamos esta idea en práctica.

En primer lugar, escribe las importaciones necesarias para utilizar HtmlUnit:

import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.html.*;
import java.io.IOException;
import java.util.List;

A continuación, inicializamos un WebClient y enviamos una solicitud HTTP al sitio web, que devolverá una HtmlPage. Es importante recordar cerrar la conexión tras recibir la respuesta, ya que el proceso seguirá ejecutándose.

WebClient webClient = new WebClient(BrowserVersion.CHROME);

try {
   HtmlPage page = webClient.getPage("https://foodnetwork.co.uk/italian-family-dinners/");

   webClient.getCurrentWindow().getJobManager().removeAllJobs();
   webClient.close();
   recipesFile.close();

} catch (IOException e) {
   System.out.println("An error occurred: " + e);
}

Vale la pena mencionar que HtmlUnit mostrará un montón de mensajes de error en la consola que te harán pensar que tu ordenador va a explotar. Bueno, no te preocupes, porque puedes ignorar tranquilamente el 98 % de ellos.

Se deben principalmente a que HtmlUnit intenta ejecutar el código JavaScript desde el servidor del sitio web. Sin embargo, algunos de ellos pueden ser errores reales que indican un problema en tu código, por lo que es mejor prestarles atención cuando ejecutes tu programa.

Puedes evitar que se muestren algunos de estos errores inútiles configurando ciertas opciones en tu WebClient:

webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setPrintContentOnFailingStatusCode(false);

Paso 4: Extracción de secciones específicas

Así pues, tenemos un documento HTML, pero queremos datos, lo que significa que debemos analizar la respuesta anterior para convertirla en información legible para los humanos.

Empecemos poco a poco: extraigamos el título de la página web. Podemos hacerlo con la ayuda del método integrado `getTitleText:`

String título = página.getTitleText();
System.out.println("Título de la página: " + título);

A continuación, vamos a extraer todos los enlaces de la página web. Para ello, contamos con los métodos integrados `getAnchors ` y `getHrefAttribute`, que extraerán todas las etiquetas `<a>` del código HTML y, a continuación, recuperarán el valordel atributo `href`:

List<HtmlAnchor> links = page.getAnchors();
for (HtmlAnchor link : links) {
   String href = link.getHrefAttribute();
   System.out.println("Link: " + href);
}

Como puedes ver, HtmlUnit ofrece muchos métodos integrados y fáciles de entender que te ahorran horas de lectura de documentación.

Pongamos un ejemplo más realista. Tenemos que extraer todas las recetas de la página web, su título y, más concretamente, su dirección.

Etiqueta de anclaje HTML resaltada para un enlace a una ficha de receta en el inspector del navegador

Si examinas una de las fichas de recetas, verás que toda la información que necesitamos se encuentra en los atributos del enlace, lo que significa que solo tenemos que buscar los enlaces que tengan la clase «card-link» y obtener sus atributos.

List<?> anchors = page.getByXPath("//a[@class='card-link']");
for (int i = 0; i < anchors.size(); i++) {
   HtmlAnchor link = (HtmlAnchor) anchors.get(i);
   String recipeTitle = link.getAttribute("title").replace(',', ';');
   String recipeLink = link.getHrefAttribute();
}

En esta ocasión utilizamos una expresión XPath para buscar enlaces a cualquier profundidad en el documento HTML. A continuación, recorremos la lista de resultados y extraemos el título y el atributo href de cada uno de ellos.

Paso 5: Exportar los datos a un archivo CSV

Este tipo de extracción puede resultar útil cuando es necesario transferir los datos a otra aplicación, en nuestro caso, un agregador de recetas. Por lo tanto, para ello, debemos exportar los datos analizados a un archivo externo.

Crearemos un archivo CSV, ya que otra aplicación puede leerlo fácilmente y se puede abrir con Excel para seguir procesándolo. Primero, solo una importación más:

import java.io.FileWriter;

A continuación, inicializamos nuestro FileWriter, que creará el archivo CSV en modo «añadir»:

FileWriter recetas = new FileWriter("recetas.csv", true);
recetas.write("id,nombre,enlace\n");

Una vez creada, también escribimos la primera línea del archivo CSV, que será el encabezado de la tabla. Ahora volvemos al bucle anterior, en el que analizamos todas las fichas de recetas, y lo completamos con la siguiente línea:

recipesFile.write(i + "," + recipeTitle + "," + recipeLink + "\n");

Ya hemos terminado de escribir en el archivo, así que ahora es el momento de cerrarlo:

recipesFile.close();

¡Genial, eso es todo! Ahora podemos ver todos los datos analizados de una forma clara, sencilla y fácil de compartir.

Hoja de cálculo con los nombres de las recetas y las URL extraídas de una página de recetas

Conclusión y alternativas

Con esto concluye nuestro tutorial. Espero que este artículo te haya resultado útil y te haya ayudado a comprender mejor el web scraping.

Como puedes imaginar, esta tecnología puede hacer mucho más que alimentar a los agregadores de recetas. Depende de ti encontrar los datos adecuados y analizarlos para crear nuevas oportunidades.

Pero, como dije al principio del artículo, los rastreadores web deben hacer frente a numerosos retos. A los desarrolladores les puede resultar emocionante resolver estos problemas con su propio rastreador web, ya que supone una gran experiencia de aprendizaje y es muy divertido. No obstante, si tienes un proyecto que terminar, quizá prefieras evitar los costes que ello conlleva (tiempo, dinero y personal).

Siempre será más fácil resolver estos problemas con una API especializada. A pesar de todos los posibles obstáculos, como la renderización de JavaScript, los proxies, los CAPTCHA, etc., WebScrapingAPI los supera todos y ofrece una experiencia personalizable. Además, hay una opción de prueba gratuita, así que, si aún no estás del todo seguro, ¿por qué no le echas un vistazo?

Acerca del autor
Raluca Penciuc, desarrolladora full-stack en WebScrapingAPI
Raluca PenciucDesarrollador full-stack

Raluca Penciuc es desarrolladora full stack en WebScrapingAPI, donde se dedica a crear rastreadores, mejorar las técnicas de evasión y buscar formas fiables de reducir la detección en los sitios web de destino.

Empieza a crear

¿Estás listo para ampliar tu recopilación de datos?

Únete a más de 2000 empresas que utilizan WebScrapingAPI para extraer datos de la web a escala empresarial sin ningún gasto de infraestructura.