Html scraping en php con curl

Html scraping en php con curl

Hoy vamos a ver algo de scraping en php, este tipo de scripts no los suelo hacer en php sino en python pero en esta ocasión he querido dedicarle este post a hacer un ejemplo de scraping en php.

Vamos a utilizar la herramienta curl para el scrapeo.

Bueno para que el ejemplo tengo algo de sentido le vamos a dar una utilidad, y será sacar los resultados de los últimos sorteos de la primitiva (juego de apuestas de España)

Vamos a sacar los últimos datos de http://www.laprimitiva.info/

Para ello vamos a escribir una función en la que vamos a pasarle el día, mes, año y el nombre del día.

function getSorteo($dia, $mes, $ano, $nombre_dia) {
        //iniciamos curl
	$ch = curl_init();
        //Aquí vamos a añadir un cero delante de día si es menor de 10 para formatear el link
	if ($dia<10) {
		$dia = "0".$dia;
	}
        if ($mes<10) { 
                 $mes = "0".$mes; 
        }
        //Le pasamos la url a curl, y formateamos el día, mes, año y el nombre del día, que siempre serán jueves y sábados
	curl_setopt($ch,CURLOPT_URL,'http://www.laprimitiva.info/loteriaprimitiva/Sorteo-'.$dia.'-'.$mes.'-'.$ano.'-'.$nombre_dia.'.html');
        //Le pasamos a curl un useragent
	curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0');
        //Le pasamos a curl el header del idioma
	curl_setopt($ch,CURLOPT_HTTPHEADER,array("Accept-Language: es-es,en"));
        //Número máximo de segundos para ejecutar funciones curl
	curl_setopt($ch,CURLOPT_TIMEOUT, 10);
        //Le pasamos True, 1, para seguir cualquier encabezado location
	curl_setopt($ch,CURLOPT_FOLLOWLOCATION, 1);
        //Le pasamos true, 1, para que nos devuelva el resultado en una string
	curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);    

	//Guardar pagina
	$result = curl_exec($ch); 
	$error = curl_error($ch); 
	curl_close($ch); //Cerramos la conexion CURL.

	//Buscamos la información dentro del html que esta dentro de estos <li>
	preg_match_all("(<li class=\"circuloverde\">(.*)</li>)siU", $result, $matches1);
        
        //Como son varios los concatenamos en una misma string
	foreach ($matches1[1] as $i) {
		$sorteo .=$i . " ";
	}
        //Eliminamos el último espacio inservible
	$sorteo = substr($sorteo, 0, -1);
        //Buscamos el número complementario que esta dentro de estos <div>
	preg_match_all("(<div class=\"circulonaranja\">(.*)</div>)siU", $result, $matches1);
	$complementario =  $matches1[1][0];;
        //Buscamos el reintegro que esta dentro de estos <div>
	preg_match_all("(<div class=\"circuloverder\">(.*)</div>)siU", $result, $matches1);
	$reintegro =  $matches1[1][0];
        //Buscamos el número joker que esta dentro de estos <span>
	preg_match_all("(<span class=\"joker\">(.*)</span>)siU", $result, $matches1);
	$joker =  $matches1[1][0];
        //Eliminamos el string "Joker " del inicio y dejamos solo el número
	$joker =  substr($joker, 6);
        //Concatenamos la fecha en una string
	$fecha = $dia.'/'.$mes.'/'.$ano;
        //Nuestra función devuelve todos los datos
	return [$fecha, $sorteo, $complementario, $reintegro, $joker];
}

Una vez acabada nuestra función con ella ya podemos sacar el resultado de un sorteo en concreto pero ahora lo que queremos es sacar unos cuantos, y ademas los mostraremos en una tabla, vamos allá.

//Vamos a indicarle el día, mes y año que queremos que empiece a scrapear
$dia_inicio = 5;
$mes_inicio = 10;
$ano_inicio = 2017;
//Guardamos en una variables el día, mes y año de este momento
$ano_actual = date('y');
$mes_actual = date('m');
$dia_actual = date('d');
//Guardamos en una variable el nombre del día con el que va a empezar a scrapear, el 5/10/2017 es jueves.
$nombre_dia = "jueves"; 
//Iniciamos la variable donde vamos a concatenar la tabla que mostrará los datos
$tabla .= "<table border>";	
$tabla .= "<tr><th scope=\"row\">Fechas</th><th>Sorteo ganador</th><th>Complementario</th><th>Reintegro</th><th>Joker</th></tr>";
//Empezamos un loop while que se cerrará cuando sobrepasemos la fecha de hoy.
while (True) {
        //llamamos a nuestra función que escribimos antes y la guardamos en una variable.
	$datos = getSorteo($dia_inicio, $mes_inicio, $ano_inicio, $nombre_dia);
	$tabla .= "<tr>";
        //Concatenamos los datos en nuestra tabla.
	$tabla .= "<th>".$datos[0]."</th>";
	$tabla .= "<th>".$datos[1]."</th>";
	$tabla .= "<th>".$datos[2]."</th>";
	$tabla .= "<th>".$datos[3]."</th>";
	$tabla .= "<th>".$datos[4]."</th>";
        //formateamos la fecha para que nuestro script nos de el nombre del día que es.
	$fecha =  DateTime::createFromFormat('d/m/Y', $datos[0]);
	$fecha = $fecha->format("Y-m-d");
        //si es Jueves sumamos 2 hasta llegar al sábado y si es sábado sumamos 5 hasta llegar al jueves
	if (date('D', strtotime($fecha)) == "Thu") {
		$dia_inicio +=2;
		$nombre_dia = "sabado";
	} else {
		$dia_inicio +=5;
		$check_suma = False;
		$nombre_dia = "jueves";	
	}
        //Guardamos en una variable el número de días que tiene el mes.
	$numeroDias = cal_days_in_month(CAL_GREGORIAN, $mes_inicio, $ano_inicio);
        //Si nos pasamos por ejemplo de un mes que tiene 31 un días, le restamos al día el número de días para obtener el correcto
        //Y sumamos uno al mes
	if ($dia_inicio>$numeroDias) {
		$dia_inicio = $dia_inicio-$numeroDias;
		$mes_inicio ++;
	}
        //Si superamos el el mes 12, obtenemos el día correcto, volvemos al mes 1 sumamos uno al año
	if ($mes_inicio>12) {
		$dia_inicio = $dia_inicio-$numeroDias;
		$mes_inicio = 1;
		$ano_inicio ++;
	}
        //y cerramos el tr
	$tabla .= "</tr>";
        //Si nos pasamos de la fecha actual rompemos el loop
	if ($dia_inicio>$dia_actual) {
		if ($mes_inicio>=$mes_actual) {
			if ($ano_inicio>=$ano_actual) {
				break;
			}
		}	
	}
}
//Cerramos al tabla y la mostramos en pantalla
$tabla .= "</table>";
echo $tabla;

Así nos mostraría por pantalla los resultados.

En breves subiré otros ejemplos en otros lenguajes un saludo y os dejo el código completo aquí abajo.

function getSorteo($dia, $mes, $ano, $nombre_dia) {
        //iniciamos curl
	$ch = curl_init();
        //Aquí vamos a añadir un cero delante de día si es menor de 10 para formatear el link
	if ($dia<10) {
		$dia = "0".$dia;
	}
        //Le pasamos la url a curl, y formateamos el dia, mes, año y el nombre del día, que siempre serán jueves y sábados
	curl_setopt($ch,CURLOPT_URL,'http://www.laprimitiva.info/loteriaprimitiva/Sorteo-'.$dia.'-'.$mes.'-'.$ano.'-'.$nombre_dia.'.html');
        //Le pasamos a curl un useragent
	curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0');
        //Le pasamos a curl el header del idioma
	curl_setopt($ch,CURLOPT_HTTPHEADER,array("Accept-Language: es-es,en"));
        //Número máximo de segundos para ejecutar funciones curl
	curl_setopt($ch,CURLOPT_TIMEOUT, 10);
        //Le pasamos True, 1, para seguir cualquier encabezado location
	curl_setopt($ch,CURLOPT_FOLLOWLOCATION, 1);
        //Le pasamos true, 1, para que nos devuelva el resultado en una string
	curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);    

	//Guardar pagina
	$result = curl_exec($ch); 
	$error = curl_error($ch); 
	curl_close($ch); //Cerramos la conexion CURL.

	//Buscamos la información dentro del html que esta dentro de estos <li>
	preg_match_all("(<li class=\"circuloverde\">(.*)</li>)siU", $result, $matches1);
        
        //Como son varios los concatenamos en una misma string
	foreach ($matches1[1] as $i) {
		$sorteo .=$i . " ";
	}
        //Eliminamos el último espacio inservible
	$sorteo = substr($sorteo, 0, -1);
        //Buscamos el número complementario que esta dentro de estos <div>
	preg_match_all("(<div class=\"circulonaranja\">(.*)</div>)siU", $result, $matches1);
	$complementario =  $matches1[1][0];;
        //Buscamos el reintegro que esta dentro de estos <div>
	preg_match_all("(<div class=\"circuloverder\">(.*)</div>)siU", $result, $matches1);
	$reintegro =  $matches1[1][0];
        //Buscamos el número joker que esta dentro de estos <span>
	preg_match_all("(<span class=\"joker\">(.*)</span>)siU", $result, $matches1);
	$joker =  $matches1[1][0];
        //Eliminamos el string "Joker " del inicio y dejamos solo el número
	$joker =  substr($joker, 6);
        //Concatenamos la fecha en una string
	$fecha = $dia.'/'.$mes.'/'.$ano;
        //Nuestra función devuelve todos los datos
	return [$fecha, $sorteo, $complementario, $reintegro, $joker];
}

//Vamos a indicarle el día, mes y año que queremos que empiece a scrapear
$dia_inicio = 5;
$mes_inicio = 10;
$ano_inicio = 2017;
//Guardamos en una variables el día, mes y año de este momento
$ano_actual = date('y');
$mes_actual = date('m');
$dia_actual = date('d');
//Guardamos en una variable el nombre del día con el que va a empezar a scrapear, el 5/10/2017 es jueves.
$nombre_dia = "jueves"; 
//Iniciamos la variable donde vamos a concatenar la tabla que mostrará los datos
$tabla .= "<table border>";	
$tabla .= "<tr><th scope=\"row\">Fechas</th><th>Sorteo ganador</th><th>Complementario</th><th>Reintegro</th><th>Joker</th></tr>";
//Empezamos un loop while que se cerrará cuando sobrepasemos la fecha de hoy.
while (True) {
        //llamamos a nuestra función que escribimos antes y la guardamos en una variable.
	$datos = getSorteo($dia_inicio, $mes_inicio, $ano_inicio, $nombre_dia);
	$tabla .= "<tr>";
        //Concatenamos los datos en nuestra tabla.
	$tabla .= "<th>".$datos[0]."</th>";
	$tabla .= "<th>".$datos[1]."</th>";
	$tabla .= "<th>".$datos[2]."</th>";
	$tabla .= "<th>".$datos[3]."</th>";
	$tabla .= "<th>".$datos[4]."</th>";
        //formateamos la fecha para que nuestro script nos de el nombre del día que es.
	$fecha =  DateTime::createFromFormat('d/m/Y', $datos[0]);
	$fecha = $fecha->format("Y-m-d");
        //si es Jueves sumamos 2 hasta llegar al sábado y si es sábado sumamos 5 hasta llegar al jueves
	if (date('D', strtotime($fecha)) == "Thu") {
		$dia_inicio +=2;
		$nombre_dia = "sabado";
	} else {
		$dia_inicio +=5;
		$check_suma = False;
		$nombre_dia = "jueves";	
	}
        //Guardamos en una variable el número de días que tiene el mes.
	$numeroDias = cal_days_in_month(CAL_GREGORIAN, $mes_inicio, $ano_inicio);
        //Si nos pasamos por ejemplo de un mes que tiene 31 un días, le restamos al día el número de días para obtener el correcto
        //Y sumamos uno al mes
	if ($dia_inicio>$numeroDias) {
		$dia_inicio = $dia_inicio-$numeroDias;
		$mes_inicio ++;
	}
        //Si superamos el el mes 12, obtenemos el día correcto, volvemos al mes 1 sumamos uno al año
	if ($mes_inicio>12) {
		$dia_inicio = $dia_inicio-$numeroDias;
		$mes_inicio = 1;
		$ano_inicio ++;
	}
        //y cerramos el tr
	$tabla .= "</tr>";
        //Si nos pasamos de la fecha actual rompemos el loop
	if ($dia_inicio>$dia_actual) {
		if ($mes_inicio>=$mes_actual) {
			if ($ano_inicio>=$ano_actual) {
				break;
			}
		}	
	}
}
//Cerramos al tabla y la mostramos en pantalla
$tabla .= "</table>";
echo $tabla;

One Reply to “Html scraping en php con curl”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Pin It on Pinterest