Como programador, en algún momento habrás necesitado acceder alguna fuente de datos pública sin poder utilizar sus propias APIs.
Con PHP podemos extraer información de una web, aunque tambien se puede hacer de otras maneras que, aún siendo más eficaces, son bastante más complicadas de programar y requiere de altos conocimientos.
Yo, como dice el título de mi blog, prefiero hacerlo programando a mi manera.
Empecemos, ¿Qué es el WEB SCRAPPING?
Funcionamiento del Scraper de Páginas Amarillas (PA)
El funcionamiento es simple aunque el desarrollo el algo confuso. Al final de esta entrada te pondré el código entero y podrás verlo en funcionamiento.
Vamos a empezar haciendo nuestra primera consulta, por ejemplo «dentistas en Castellón».
En este caso, nos ofrece 91 resultados.
Capturamos esta información desde nuestro formulario, al que hemos de añadir el LINK de la consulta que hemos realizado en PA, que sería el siguiente:
https://www.paginasamarillas.es/search/dentistas/all-ma/castellon/all-is/castellon/all-ba/all-pu/all-nc/1?what=dentistas&where=castellon&ub=false&qc=true
Recibimos esta información y con éste sencillo código…
$consulta = file_get_contents($link_pag_am); $resultados_totales= preg_replace('/[^0-9]+/', '', (strip_tags(extraeRegexp($consulta, '<div class="negocio">', '</span>')[0]))); $paginas= ceil($resultados_totales/30);
…contamos el total de resultados (ya hemos dicho que en este caso son 91), lo dividimos entre 30, que son los resultados a mostrar por página y lo redondeamos hacia arriba por si hay menos de 30 resultados.
Extraer datos.
Ésta es la función más importante del programa, ya que se encarga de buscar en los resultados la información que queremos extraer. El funcionamiento es muy simple, le damos la cadena ($cadena) que hemos extradido y le decimos DESDE DONDE ($inicio) y HASTA DONDE ($fin) queremos que nos busque la información.
function extraeRegexp($cadena, $inicio, $fin) { preg_match_all('#' . $inicio . '(.*?)' . $fin . '#', $cadena, $matches); return $matches[1]; }
Ésta función la utilizaremos cada vez que queramos un dato.
Mostrar tabla de resultados
Ahora que ya sabemos cuántas páginas de resultados tenemos, procederemos a extraer toda la información que necesitamos. Para esto, utilizaremos la segunda funcion que hemos llamado mostrarTabla();
En el inicio tenemos este código…
for ($i = 1; $i <= $paginas; $i++) { $url = $link_pag_am; $web = file_get_contents($url); $urls = extraeRegexp($web, "<div class=\"envio-consulta\"><a href=\"", "\""); $total = array_merge($total, $urls); }
…que nos devuelve un array con todas las empresas que se muestran en cada una de las páginas.
Ahora ya podemos empezar a recorrer dicho array con un simple foreach;
foreach ($total as $url) { $web = file_get_contents($url); $nombre = extraeRegexp($web, '<h1 itemprop="name">', '</h1>')[0]; $categoria = extraeRegexp($web, '<span class="category">', '</span>')[0]; $telefono = extraeRegexp($web, '<span itemprop="telephone">', '</span>')[0]; $direccion = extraeRegexp($web, '<span itemprop="streetAddress">', '</span>')[0]; $cp = extraeRegexp($web, '<span itemprop="postalCode">', '</span>')[0]; $ciudad = extraeRegexp($web, '<span itemprop="addressLocality">', '</span>')[0]; $provincia = @extraeRegexp($web, '<span class="addressState">', '</span>')[0]; $webaddress = @str_replace("?utm_campaign=paginasamarillas&utm_source=paginasamarillas&utm_medium=referral", "", extraeRegexp($web, 'class="fa icon-link"></i><a href="', '"')[0]); }
Y una vez llegues aquí, sólo te queda utilizar tus conocimientos para mostrar la información como necesites. Puedes generar una simple tabla, guardarlos en una base de datos o generar un archivo para conservarlos o enviarlos.
Seguramente, en función de la página de donde extraigas la información, necesitarás modificar el código para adaptarlo a la web que estás «scrapeando».
Espero que esta pequeña aportación te sea de utilidad. Aquí te dejo el código completo que yo he adaptado para mí y un link para que puedas probarlo.
DEMOSTRACIÓN FUNCIONAMIENTO
<html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> </head> <body> <div> <form class="form-control" style="background: black;padding: 2%"> <input type="hidden" name="action" value="insert"> <h5 style="color:white">Inserta la URL de la consulta en Paginas Amarillas:</h5> <input type="text" name="linkPA" class="form-control"> <input style="margin-top: 5px" type="submit" class="btn btn-xs btn-info" value="CONSULTAR"> </form> <div id="loading" style="z-index: 999999999"> <img style="margin-left:40%;width:20%" src="loader.gif"/><h6 style="text-align:center;font-weight:bold">CARGANDO RESULTADOS</h6> </div> </div> <?php error_reporting(0); $action = filter_input(INPUT_GET, 'action'); $link_pag_am = filter_input(INPUT_GET, 'linkPA', FILTER_SANITIZE_STRING); $consulta = file_get_contents($link_pag_am); $resultados_totales= preg_replace('/[^0-9]+/', '', (strip_tags(extraeRegexp($consulta, '<div class="negocio">', '</span>')[0]))); $paginas= ceil($resultados_totales/30); if ($action == 'insert' && !empty($link_pag_am)) { mostrarTabla($link_pag_am,$paginas); } function extraeRegexp($cadena, $inicio, $fin) { preg_match_all('#' . $inicio . '(.*?)' . $fin . '#', $cadena, $matches); return $matches[1]; } function mostrarTabla($link_pag_am,$paginas) { $total = []; for ($i = 1; $i <= $paginas; $i++) { $url = $link_pag_am; $web = file_get_contents($url); $urls = extraeRegexp($web, "<div class=\"envio-consulta\"><a href=\"", "\""); $total = array_merge($total, $urls); } ?> <div> <table class="table table-sm table-striped table-bordered" style="width:100%"> <tr style="background:#847f7f; color:black; font-weight:bold"> <td>#</td><td>NOMBRE</td><td>PROVINCIA</td><td>CIUDAD</td><td>WEB</td> </tr> <?php $number = 0; foreach ($total as $url) { $web = file_get_contents($url); $webaddress = @str_replace("?utm_campaign=paginasamarillas&utm_source=paginasamarillas&utm_medium=referral", "", extraeRegexp($web, 'class="fa icon-link"></i><a href="', '"')[0]); $urlparts = parse_url($webaddress); $scheme = $urlparts['scheme']; if ($scheme === 'https' || $scheme === 'http') { $number++; //CONTADOR DE RESULTADOS----------------- $nombre2 = extraeRegexp($web, '<h1 itemprop="name">', '</h1>')[0]; $nombre= preg_replace("%(<span.*?>)(.*?)(<\/span.*?>)%is","",$nombre2); $ciudad = extraeRegexp($web, '<span itemprop="addressLocality">', '</span>')[0]; $provincia = @extraeRegexp($web, '<span class="addressState">', '</span>')[0]; if (is_null($provincia)) { $provincia = $ciudad; } ?> <tr> <td><?= $number ?></td><td><?= $nombre ?></td><td><?= $provincia ?></td><td><?= $ciudad ?></td><td><a target="_blank" href="<?= $webaddress ?>"><?= $webaddress ?></a></td> </tr> <?php } /* $categoria = extraeRegexp($web, '<span class="category">', '</span>')[0]; $telefono = extraeRegexp($web, '<span itemprop="telephone">', '</span>')[0]; $direccion = extraeRegexp($web, '<span itemprop="streetAddress">', '</span>')[0]; $cp = extraeRegexp($web, '<span itemprop="postalCode">', '</span>')[0]; */ } ?> </table> </div> <?php } ?> <script> $(document).ready(function(){ $('#loading').hide(); $('form').submit(function(){ $('#loading').show(); }); }); </script> </body> </html>
Hola, muy buen artículo, el problema es que me queda un poco lejos en cuanto a conocimientos. Hay alguna manera de acceder a algo programado para scrapear las paginas amarillas y obtener los emails de las empresas .
Si me das un correo electrónico te escribo por privado.
Muchas gracias