Guía completa de web scraping con PHP

Autor :

Reaccionar :

Comentario

PHP no solo sirve para crear sitios web dinámicos. También puede convertirse en un aliado para recopilar datos en línea.

Gracias a las bibliotecas especializadas, podrá configurar un rascador eficaz. Veamos cómo.

PHP facilita el web scraping, lo que permite recuperar y analizar rápidamente datos directamente de los sitios web.
PHP facilita el web scraping, lo que permite recuperar y analizar rápidamente datos directamente desde sitios web. ©Christina para Alucare.fr

Requisitos previos para el scraping con PHP

Antes de empezar, asegúrate de :

  • ✅ Tener programación básica con PHP.
  • ✅ Tener conocimientos de HTML y CSS para seleccionar los datos que deben extraerse.
  • ✅ Saber utilizar Marque. Es una herramienta para gestionar las dependencias de PHP para instalar bibliotecas de scraping como Guzzle, Symfony DomCrawler o Goutte.
  • ✅ Tener un servidor web local para ejecutar su código (XAMPP, WAMP o MAMP).
  • ✅ Tener un editor de código para escribir sus scripts PHP.

¿Qué herramientas son esenciales para el web scraping con PHP?

PHP por sí solo no es suficiente. Aquí están los bibliotecas que hacen que el raspado sea rápido y eficaz.

1. Guzzle : El cliente HTTP

Guzzle es la biblioteca más utilizada para enviar peticiones HTTP. Para instalarlo con Marqueabra su terminal, vaya a la carpeta de su proyecto y escriba el comando :

composer require guzzlehttp/guzzle

Composer descarga la biblioteca y la hace utilizable directamente en su código.

He aquí un ejemplo de código sencillo para recuperar el contenido de una URL :

request('GET', $url);

    // Recuperar el código HTTP
    $statusCode = $response->getStatusCode();

    // Recuperar el contenido de la página
    $content = $response->getBody()->getContents();

    echo "Código HTTP : " . $statusCode . PHP_EOL;
    echo "Contenido de la página:" . PHP_EOL;
    echo $content;

} catch (\Exception $e) {
    echo "Error: " . $e->getMessage();
}

2. Symfony DomCrawler y Goutte: extracción de datos

Hay dos bibliotecas muy utilizadas para navegar y analizar HTML:

  • Symfony DomCrawler que le permite navegar por HTML utilizando selectores CSS y dirigirse a elementos específicos.
  • Drop que es un wrapper para Guzzle y DomCrawler, simplifica enormemente el proceso de scraping.

Ejemplo con Symfony DomCrawler :

request('GET', 'https://exemple.com');

$html = $response->getBody()->getContents();
$crawler = new Crawler($html);

// Selección por clase
$crawler->filter('.my-class')->each(function ($node) {
    echo $node->texto() . PHP_EOL;
});

// Selección por ID
$crawler->filter('#mon-id')->each(function ($node) {
    echo $node->text() . PHP_EOL;
});

// Selección por etiqueta
$crawler->filter('h1')->each(function ($node) {
    echo $node->text() . PHP_EOL;
});

Ejemplo con Goutte

request('GET', 'https://exemple.com');

// Selección por clase
$crawler->filter('.ma-class')->each(function ($node) {
    echo $node->text() . PHP_EOL;
});

// Selección por ID
$crawler->filter('#mon-id')->each(function ($node) {
    echo $node->text() . PHP_EOL;
});

// Selección por etiqueta
$crawler->filter('p')->each(function ($node) {
    echo $node->text() . PHP_EOL;
});

3. Otras bibliotecas y herramientas

Para ir más allá, aquí tienes otras opciones:

  • 🔥 PHP-Scraper : es una biblioteca PHP que facilita la extracción de información de páginas web gestionando las complejidades del HTML y los selectores. Es muy utilizada por los desarrolladores en sus proyectos a través de Composer.
Instalación de # con Composer
compose require fabpot/goutte
  

request('GET', 'https://example.com');
$title = $crawler->filter('title')->text();

echo "Título de la página: " . $ítulo;
  
  • 🔥 Datos brillantes : es una plataforma profesional para la recopilación de datos a gran escala con proxys integrados.
Bright Data: la herramienta de raspado web más completa.
Bright Data: la herramienta de web scraping más completa. ©Christina para Alucare.fr
  • 🔥 ScraperAPI : es un servicio de scraping web basado en la nube, accesible a través de una API. En lugar de utilizar bibliotecas locales para realizar todo el trabajo, se envía una simple solicitud a la API de ScraperAPI especificando la URL de la página que se desea rastrear.

¿Cómo puedo crear un raspador web sencillo en PHP?

He aquí un tutorial para crear un scraper funcional en PHP :

Paso 1: Instalación de las dependencias

Utilice Marque instalar Drop gracias a la :


compose require fabpot/goutte

Paso 2: Recuperar el contenido de una página

Hacer una Solicitud HTTP GET y rhojear el contenido HTML de la página utilizando Goutte con el comando :

request('GET', $url);

// Recuperar el HTML en bruto si es necesario
$html = $crawler->html();
echo substr($html, 0, 500) . '...'; // vista previa

Paso 3: Extraer los datos

Una vez que haya recuperado el contenido HTML de la página, el objetivo es extraer datos específicos.

👉 Aquí hay un ejemplo de código PHP para raspar los títulos de una página blog con Goutte, utilizando un selector CSS para orientar el <h2> en los elementos <article>.

<?php
require 'vendor/autoload.php';

use Goutte\Client;

$client = new Client();
$url = 'https://exemple.com/blog'; // Remplacez par l'URL de votre page cible

// Faire une requête GET pour récupérer la page
$crawler = $client->request('GET', $url);

// Sélectionner les éléments <h2> dans <article> avec le sélecteur CSS
$titres = [];

$crawler->filter('article h2')->each(function ($node) use (&$titres) {
    // Récupérer le texte du titre
    $titres[] = trim($node->text());
});

// Afficher les titres extraits
print_r($titres);
?>

En este ejemplo:

  • Utilizamos el selector CSS artículo h2 para orientar los títulos de los artículos en <h2> dentro de las etiquetas <article>.
  • El texto de cada título se extrae mediante la función texto(), y lo añadimos a la tabla. $ítulos.
  • Los títulos se muestran con print_r($itulos);.

Él Selectores CSS (o XPath) también puede utilizarse para extracto atributos elementos HTML. Por ejemplo, si cada título de blog es un enlace en una etiqueta <a>, podemos extraer el atributo href para obtener las URL de los artículos.

👉 Aquí hay un ejemplo con Goutte para extraer el enlaces artículos :

request('GET', $url);

// Seleccionar los enlaces en los títulos
$itulos = [];

$crawler->filter('artículo h2 a')->each(function ($node) use (&$itles) {
    $itle = trim($node->text());
    $link = $node->attr('href'); // Extraer atributo href

    // Añadir el título y la URL a la tabla
    $itulos[] = [
        title' => $itle,
        url' => $lien,
    ];
});

// Mostrar los resultados
print_r($itulos);
?>

En este ejemplo:

  • Seleccionamos los enlaces contenidos en el <a> dentro de las etiquetas <h2> en los elementos <article>.
  • Recuperamos el atributo href de cada enlace con el attr('href').
  • Los títulos y sus URL se añaden a la tabla $ítulosy luego se muestra con print_r($itulos);.

👉 El cuadro $ítulos contendrá elementos tanto con el título y el enlace de cada elemento. He aquí un ejemplo del formato de los datos devueltos:

Matriz
(
    [0] => Array
        (
            [title] => Título del artículo 1
            [url] => /artículo1
        )

    [1] => Array
        (
            [title] => Título del artículo 2
            [url] => /artículo2
        )
)

En este ejemplo:

  • Cada elemento de la matriz es una matriz asociativa con dos claves: título para el título del artículo y URL para la URL correspondiente.
  • Los datos extraídos se presentan en forma de tabla de dos niveles, en la que cada entrada contiene un título y su enlace asociado.

Etapa 4: Estructuración y almacenamiento de datos

Una vez extraídos los datos, es importante organizarlos correctamente. Para ello, vamos a estructurarlos en un archivo Tabla PHPy luego exportarlos en un formato estructurado como JSON Donde CSV.

request('GET', $url);

// Extraer títulos y URLs en una tabla estructurada
$data = [];
$crawler->filter('articulo h2 a')->each(function ($node) use (&$data) {
    $data[] = [
        title' => trim($node->text()), // Extraer título
        url' => $node->attr('href'), // Extraer el atributo href (URL)
    ];
});

// Mostrar los datos extraídos
print_r($data);
?>

Una vez organizados los datos, puede exportarlos en el formato JSONque es útil para las API o para su uso en aplicaciones web:

<?php
// Exporter les données en JSON
file_put_contents('export.json', json_encode($data, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));

echo "Les données ont été exportées en JSON dans 'export.json'.";
?>

El expediente export.json se creará en un formato legible, que podría tener este aspecto:

[
    {
        "title": "Título del artículo 1",
        "url": "/article1"
    },
    {
        "title": "Título del artículo 2",
        "url": "/artículo2"
    }
]

Si desea exportar los datos como una tabla CSV, puede utilizar fputcsv para escribir los datos en un archivo CSV :

<?php
// Exporter les données en CSV
$fp = fopen('export.csv', 'w');

// Ajouter l'en-tête (titres des colonnes)
fputcsv($fp, ['title', 'url']);

// Ajouter chaque ligne de données
foreach ($data as $row) {
    fputcsv($fp, [$row['title'], $row['url']]);
}

// Fermer le fichier
fclose($fp);

echo "Les données ont été exportées en CSV dans 'export.csv'.";
?>

El expediente export.csv se verá así:

título,url
Título del artículo 1,/artículo1
Título del artículo 2,/artículo2

¿Cómo puedo hacer frente a los problemas comunes de web scraping en PHP?

Durante una operación de web scraping en PHPSin embargo, pueden surgir problemas. He aquí las soluciones para los más comunes.

1. Gestión de errores

  • Errores de conexión

A veces, la solicitud ni siquiera llega al servidor. Puede encontrarse con “Sin red”, “URL no válida”, “Servidor inaccesible”etc. En este caso, un try/catch para evitar que su script se detenga bruscamente.

👉 Aquí tienes un ejemplo usando Guzzle :

request('GET', 'https://example.com/api/data');
        
        // Comprueba si la petición se ha realizado correctamente
        if ($response->getStatusCode() === 200) {
            // Procesar la respuesta en caso afirmativo
            $body = $response->getBody();
            echo "Datos recibidos : " . $body;
        }
        
    } catch (RequestException $e) {
        // Capturar errores de conexión y petición
        if ($e->hasResponse()) {
            // Mostrar el código de error si está disponible
            echo "Error de solicitud: " . $e->getResponse()->getStatusCode();
        } else {
            // Si la conexión falla (por ejemplo, servidor inalcanzable)
            echo "Error de conexión: " . $e->getMessage();
        }
    }
}

// Llamar a la función
make_request_with_guzzle();
?>
  • Códigos de estado HTTP

Aunque la conexión funcione, el servidor puede responder con un error (404 = página no encontrada, 500 = error de Internetetc.). Puede comprobar el código de estado con getStatusCode().

request('GET', 'https://example.com/api/data');
        
        // Comprueba el código de estado de la respuesta
        $status_code = $response->getStatusCode();
        
        // Comprueba si la solicitud se ha realizado correctamente
        if ($status_code === 200) {
            // Procesar la respuesta en caso afirmativo
            $body = $response->getBody();
            echo "Respuesta correcta con código: " . $status_code . "
";
            echo "Datos recibidos: " . $body;
        } elseif ($status_code === 404) {
            echo "Error 404 : Página no encontrada
";
        } elseif ($status_code === 500) {
            echo "Error 500 : Error interno del servidor
";
        } else {
            echo "Código de estado: " . $status_code . "
";
        }
        
    } catch (RequestException $e) {
        // Capturar errores de conexión y petición
        if ($e->hasResponse()) {
            // Mostrar el código de error HTTP si está disponible
            echo "Error HTTP: " . $e->getResponse()->getStatusCode() . "
";
        } else {
            // En caso de fallo de conexión (por ejemplo, servidor inalcanzable)
            echo "Error de conexión: " . $e->getMessage();
        }
    }
}

// Llamar a la función
make_request_with_guzzle();
?>
  • Errores de análisis sintáctico 

El análisis sintáctico es el análisis del HTML por parte de su rastreador. Si la página está mal formada, DomCrawler o Goutte pueden bloquearse o no devolver ningún resultado.

Para gestionar este tipo de error, siempre hay que comprobar que el contenido existe antes de intentar extraerlo. Utilice condiciones. (cuenta(), filter()...) para asegurarse de que el elemento deseado está presente. A continuación, encierre el análisis sintáctico entre try/catch para evitar que el script se bloquee.

request('GET', 'https://example.com');

        // Comprueba que el elemento de destino existe antes de intentar extraerlo
        $elements = $crawler->filter('div.target-element');
        
        if ($elements->count() > 0) {
            // El elemento está presente, podemos extraerlo
            $content = $elements->first()->text();
            echo "Contenido extraído: " . $content;
        } else {
            // No se encuentra el elemento
            echo "No se ha encontrado el elemento de destino en la página;
        }
        
    } catch (Exception $e) {
        // Captura errores de análisis
        echo "Error al analizar la página: " . $e->getMessage();
    }
}

// Llamar a la función
función scrape_website();
?>

2. Evitar las limitaciones

Algunos sitios utilizan medidas de protección para dificultar el scraping.

  • Bloqueo por IP Puede utilizar proxies como los de la plataforma Bright Data.
  • JavaScript por defecto, PHP no puede ejecutar JavaScript. Para ello, es necesario utilizar un navegador sin interfaz gráfica (headless browser).
  • Robots.txt Antes de proceder al desguace, es importante consultar este expediente para actuar de forma legal y responsable.

preguntas frecuentes

¿Es legal el web scraping?

📌 El legalidad del web scraping es un tema complejo. En Francia, como en todas partes, todo depende del marco jurídico, de los datos recogidos y de la forma en que se utilicen.

¿Cuál es la diferencia entre web scraping y web crawling?

  • la raspado web es el hecho de extraer datos precisos de un sitio web.
  • la rastreo web es el acto de navegar por las páginas para indexarlas.
El rastreo web consiste en explorar y descubrir automáticamente varios sitios web, mientras que el scraping web se centra en extraer datos precisos de un objetivo concreto mediante un software especializado.
El rastreo web consiste en explorar y descubrir automáticamente varios sitios web, mientras que el scraping web se centra en la extracción de datos precisos de un objetivo específico mediante el uso de software especializado. ©Christina para Alucare.fr

¿Cómo hago scraping de un sitio que requiere autenticación (login)?

Para raspar un sitio que requiere autenticación, debe simular la conexión. Con PHP, la solución más común es Guzzle.

Se envían los identificadores mediante una petición POST y se mantiene la sesión abierta para recuperar las páginas protegidas.

¿Cómo se gestiona el scraping de sitios con páginas dinámicas cargadas en AJAX?

⚠ Como recordatorio, PHP no puede ejecutar código JavaScript del lado del cliente.

Para raspar este tipo de página con PHP, puede utilice BrowserShotuna biblioteca que utiliza un navegador real en segundo plano (Headless Chrome/Chromium) para cargar la página y ejecutar el JavaScript.

Otra solución es integrar PHP con herramientas basadas en Node.jscomo Puppeteer para generar el HTML renderizado y luego recuperar los datos de PHP.

Para todo tipo de web scraping con páginas dinámicas, también puede utilizar herramientas especializadas denominadas navegadores sin cabeza.

¿Existen alternativas a PHP para el web scraping?

Sí, varias lenguas son populares:

  • Python con sus potentes bibliotecas como BeautifulSoup y Scrapy.
  • Node.js que es muy eficaz para el scraping de sitios web dinámicos, utilizando librerías como Puppeteer o Cheerio.
El web scraping con Python funciona utilizando librerías como BeautifulSoup o Scrapy para navegar por páginas web y extraer automáticamente los datos deseados.
El web scraping con Python funciona utilizando librerías como BeautifulSoup o Scrapy para navegar por páginas web y extraer automáticamente los datos deseados. Cristina para Alucare.fr

¿Cómo programar un “scraper” de forma ética y responsable?

Para raspar de forma ética, es necesario :

  1. ✔ Compruebe el archivo robots.txt para conocer las normas.
  2. Limite la frecuencia de sus solicitudes para no sobrecargar el servidor del sitio.
  3. Respetar las condiciones de uso del sitio web.
  4. No recopilar datos personales sin autorización.

✅ En resumen raspado web es una práctica poderosa, pero debe utilizarse de forma metódica y responsable.

👉 Y tú, ¿has creado alguna vez un scraper en PHP o en otro idioma? Comparta sus experiencias en la sección de comentarios.

¿Te gusta? ¡Compártelo!

Este contenido es originalmente en francés (Véase el editor justo debajo). Se ha traducido y revisado en varios idiomas utilizando Deepl y/o la API de Google Translate para ofrecer ayuda en el mayor número de países posible. Esta traducción nos cuesta varios miles de euros al mes. Si no es 100 % perfecta, déjanos un comentario para que podamos arreglarlo. Si estás interesado en corregir y mejorar la calidad de los artículos traducidos, ¡envíanos un correo electrónico a través del formulario de contacto!
Agradecemos sus comentarios para mejorar nuestros contenidos. Si desea sugerirnos mejoras, utilice nuestro formulario de contacto o deje un comentario a continuación. Sus comentarios siempre nos ayudan a mejorar la calidad de nuestro sitio web Alucare.fr


Alucare es un medio de comunicación independiente. Apóyanos añadiéndonos a tus favoritos de Google News:

Publicar un comentario en el foro de debate