Ayuda con CURL y matches

  • Autor Autor jhonlozanot
  • Fecha de inicio Fecha de inicio
jhonlozanot

jhonlozanot

VIP
Eta
Verificado
Verificación en dos pasos activada
Verificado por Binance
Suscripción a IA
Soy nuevo en esto de php y estoy practicando parsear html, ojala alguien me pueda ayudar la verdad soy nobato, explico lo que quiero lograr.


Este es mi codigo html donde el cual quiero sacar datos especificos el cual es el nombre y apellidos.

HTML:
					<td width="35%">Apellido paterno</td>
					<td style="background-color: white">OSORIO                                  </td>
				</tr>
				<tr>
					<td width="35%">Apellido materno</td>
					<td style="background-color: white">MENDOZA                                 </td>
				</tr>
				<tr>
					<td width="35%">Nombres</td>
					<td style="background-color: white">PEPE                               </td>


Y este es mi codigo php con el cual quiero parsear los datos:
PHP:
<?php
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, 'localhost/bot/index.php');
	curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
	curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept-Language: es-es,en"));
	curl_setopt($ch, CURLOPT_TIMEOUT, 10);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	$result = curl_exec($ch);
	$error = curl_error($ch);
	curl_close($ch); 
	//Parsear
	preg_match_all("(<td width=\"35%\">Apellido paterno</td> <td style=\"background-color: white\">(.*)</td>)siU", $result, $matches1);
    preg_match_all("(<td width=\"35%\">Nombre materno</td> <td style=\"background-color: white\">(.*)</td>)siU", $result, $matches2);
  	preg_match_all("(<td width=\"35%\">Nombres</td> <td style=\"background-color: white\">(.*)</td>)siU", $result, $matches3);
	
	$appaterno = $matches1[1][0];
	$apmaterno = $matches2[1][0];
	$nombres = $matches2[1][0];
?>
<style>

.container
{
	background: white;
	font-family: Helvetica;
	font-size: 19px;
	border-radius: 1em;
	box-shadow: 0px 5px 5px rgba(0,0,0,0.5);
	margin: 1em auto;
	padding: 1em;
	width: 25%;
}
</style>
<div class="container">
	<?="Datos de Persona:</br>"?>
	<?="Apellido Paterno: <b>" . $appaterno.'</b>'?>
	<?="Apellido Materno: <b>" . $apmaterno.'</b>'?>
	<?="Nombre: <b>" . $nombres.'</b>'?>

</div>

Me tira el siguiente error:
Insertar CODE, HTML o PHP:
Notice: Undefined offset: 0 in C:\xampp\htdocs\bot\bot.php on line 18

Notice: Undefined offset: 0 in C:\xampp\htdocs\bot\bot.php on line 19

Notice: Undefined offset: 0 in C:\xampp\htdocs\bot\bot.php on line 20
 
Los espacios y saltos de línea están ocasionando que no haya coincidencias, además de que los índices donde defines las variables, no están bien...

Reemplaza esto:

PHP:
preg_match_all("(<td width=\"35%\">Apellido paterno</td> <td style=\"background-color: white\">(.*)</td>)siU", $result, $matches1);
preg_match_all("(<td width=\"35%\">Nombre materno</td> <td style=\"background-color: white\">(.*)</td>)siU", $result, $matches2);
preg_match_all("(<td width=\"35%\">Nombres</td> <td style=\"background-color: white\">(.*)</td>)siU", $result, $matches3);
    
$appaterno = $matches1[1][0];
$apmaterno = $matches2[1][0];
$nombres = $matches2[1][0];

Por esto:

PHP:
preg_match_all("(<td style=\"background-color: white\">(.*)</td>)siU", $result, $matches);
$appaterno = $matches[1][0];
$apmaterno = $matches[1][1];
$nombres = $matches[1][2];

Cuando necesites saber los índices de los arrays, haz un print_r, en este caso sería print_r($matches), te aconsejo antes poner un echo '<pre>'; para que le de formato y sea más fácil la lectura.

Prueba y me cuentas :encouragement:
 
Los espacios y saltos de línea están ocasionando que no haya coincidencias, además de que los índices donde defines las variables, no están bien...

Reemplaza esto:

PHP:
preg_match_all("(<td width=\"35%\">Apellido paterno</td> <td style=\"background-color: white\">(.*)</td>)siU", $result, $matches1);
preg_match_all("(<td width=\"35%\">Nombre materno</td> <td style=\"background-color: white\">(.*)</td>)siU", $result, $matches2);
preg_match_all("(<td width=\"35%\">Nombres</td> <td style=\"background-color: white\">(.*)</td>)siU", $result, $matches3);
    
$appaterno = $matches1[1][0];
$apmaterno = $matches2[1][0];
$nombres = $matches2[1][0];

Por esto:

PHP:
preg_match_all("(<td style=\"background-color: white\">(.*)</td>)siU", $result, $matches);
$appaterno = $matches[1][0];
$apmaterno = $matches[1][1];
$nombres = $matches[1][2];

Cuando necesites saber los índices de los arrays, haz un print_r, en este caso sería print_r($matches), te aconsejo antes poner un echo '<pre>'; para que le de formato y sea más fácil la lectura.

Prueba y me cuentas :encouragement:

Gracias!! me funciono no sabia que los saltos de linea de las tablas no dejaría encontrar coincidencias,

use tal como me dijiste
echo '<pre>';
print_r($matches);
echo '</pre>';

y vi los indices del array

saludos
 
Última edición:
Si bueno, en este caso ya da igual porque si te das cuenta solo vamos a buscar coincidencias en las celdas white. Por cierto, si necesitas extraer datos así, pero donde se repiten (supongamos que hay N cantidad de nombres), lo puedes hacer con foreach, te aconsejo buscar información sobre "preg_match_all foreach php".

Las expresiones regulares se caracterizan un poco por generar uno que otro dolor de cabeza jeje, estúdialas mucho y ten paciencia si eso te sucede.

Saludos :encouragement:
 
También puedes hacerlo de esta forma

PHP:
$html = '<table>'
  .'<tr><td width="35%">Apellido paterno</td><td style="background-color: white">OSORIO</td></tr>'
  .'<tr><td width="35%">Apellido materno</td><td style="background-color: white">MENDOZA</td></tr>'
  .'<tr><td width="35%">Nombres</td><td style="background-color: white">PEPE</td></tr>'
  .'</table>';

$dom = new DOMDocument();
$dom->loadHTML($html);

$tr = $dom->getElementsByTagName('tr');

foreach($tr as $row){
  $td = $row->getElementsByTagName('td');
  
  echo $td->item(0)->textContent .': '. $td->item(1)->textContent .'<br />';
}
 
También puedes hacerlo de esta forma

PHP:
$html = '<table>'
  .'<tr><td width="35%">Apellido paterno</td><td style="background-color: white">OSORIO</td></tr>'
  .'<tr><td width="35%">Apellido materno</td><td style="background-color: white">MENDOZA</td></tr>'
  .'<tr><td width="35%">Nombres</td><td style="background-color: white">PEPE</td></tr>'
  .'</table>';

$dom = new DOMDocument();
$dom->loadHTML($html);

$tr = $dom->getElementsByTagName('tr');

foreach($tr as $row){
  $td = $row->getElementsByTagName('td');
  
  echo $td->item(0)->textContent .': '. $td->item(1)->textContent .'<br />';
}

Gracias por el aporte, se ve mas simplificado con DOM
 
Atrás
Arriba