Foro de elhacker.net

Programación => PHP => Mensaje iniciado por: #Aitor en 8 Enero 2014, 18:47 pm



Título: Problemas con cURL
Publicado por: #Aitor en 8 Enero 2014, 18:47 pm
Buenas... estaba siguiendo unos 'cursos' si así se pueden llamar de cURL, en el cual uno de los ejercicios, era extraer los subscriptores que tenía un canal de youtube...

El problema está, en que, por alguna razón no puedo extraer nada, porque no guarda nada, o al menos el array se encuentra completamente vacio...

Código
  1. <?php
  2. // Variable url.
  3. $url = 'http://www.youtube.com/user/'.$_POST['user'].'/about';
  4.  
  5. // Curl-bot.
  6. $ch = curl_init();
  7. curl_setopt($ch, CURLOPT_URL, $url);
  8. curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSTE 5.01; Windows NT 5.0');
  9. curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept-Language: es-es,en'));
  10. curl_setopt($ch, CURLOPT_TIMEOUT, 10);
  11. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  12. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  13.  
  14. // Guardar en página.
  15.  
  16. $result = curl_exec($ch);
  17. $error = curl_error($ch);
  18. curl_close($ch);
  19. echo $error;
  20.  
  21.  
  22. // Parsear.
  23.  
  24. preg_match_all('(<ul class="about-stats"><li class="about-stat"><span class="about-stat-value">(.*)</span> suscriptores</li>)', $result, $sus);
  25. $susR = $sus[1][0];
  26.  print_r($sus);
  27.  echo 'Suscriptores: ' . $susR;
  28.  
  29. ?>

Formulario.html
Código
  1. <html>
  2. <head><title>Prueba con bots</title></head>
  3.  
  4. <body>
  5.  
  6. <form method="POST" action="bots.php">
  7. <input type="text" name="user"/>
  8. <input type="Submit" value="INTRODUCIR USUARIO DE YOUTUBE"/>
  9. </form>
  10.  
  11. </body>
  12. </html>



Resultado:
Código
  1. Notice: Undefined offset: 1 in C:\xampp1\htdocs\PHP\Bots\bots.php on line 25
  2. Array ( [0] => Array ( ) [1] => Array ( ) ) Suscriptores:


Título: Re: Problemas con cURL
Publicado por: #Aitor en 9 Enero 2014, 01:51 am
Ya está solucionado, pero no termino de entender por qué, con esto si funciona:

Código
  1. preg_match_all("(<span class=\"about-stat-value\">(.*)</span> suscriptores)", $result, $sus);

Pero con el otro no, cuando es el mismo código pero un poquito más largo, de hecho como este había uno identico, por lo que pensé que tendría que coger más trozo para que no se equivocase...

Si alguien pudiese aclararme eso, se lo agradezco, saludos!


Título: Re: Problemas con cURL
Publicado por: Shell Root en 9 Enero 2014, 06:57 am
Supongo, aunque no estoy seguro, que es porque tiene un salto de linea, es decir,... es diferente ver esto:
Código
  1. <li class="about-stat">
  2.   <span class="about-stat-value">88</span> suscriptores
  3. </li>

a esto:
Código
  1. <li class="about-stat"><span class="about-stat-value">88</span> suscriptores</li>



Ahora para que se entienda lo que quiero decir, realizamos un preg_replace para que elimine todos los saltos de linea, así:
Código
  1. $result = preg_replace("/\r\n+|\r+|\n+|\t+/i", " ", $result);
Printeamos la variable de $result y vemos el código fuente queda en 1 sola linea, buscamos lo que nos interesa y vemos que quedo así:
Código
  1. <li class="about-stat">         <span class="about-stat-value">88</span> suscriptores       </li>
Queriendo decir qué si ponemos esa string para que matchee en el preg_match_all, debería de darnos el resultado real:
Código
  1. preg_match_all('(<li class="about-stat">         <span class="about-stat-value">(.*)</span> suscriptores       </li>)', $result, $sus);



De momento sólo se me ocurre agregarle el salto de linea para evitar el preg_replace, quedando: -no me la llevo muy bien con las expresiones regulares, así que sale medio feo-
Código
  1. preg_match_all('(<li class="about-stat">([\n*])<span class="about-stat-value">(.*)</span> suscriptores)', $result, $sus);


Título: Re: Problemas con cURL
Publicado por: #Aitor en 9 Enero 2014, 12:15 pm
Supongo, aunque no estoy seguro, que es porque tiene un salto de linea, es decir,... es diferente ver esto:
Código
  1. <li class="about-stat">
  2.   <span class="about-stat-value">88</span> suscriptores
  3. </li>

a esto:
Código
  1. <li class="about-stat"><span class="about-stat-value">88</span> suscriptores</li>



Ahora para que se entienda lo que quiero decir, realizamos un preg_replace para que elimine todos los saltos de linea, así:
Código
  1. $result = preg_replace("/\r\n+|\r+|\n+|\t+/i", " ", $result);
Printeamos la variable de $result y vemos el código fuente queda en 1 sola linea, buscamos lo que nos interesa y vemos que quedo así:
Código
  1. <li class="about-stat">         <span class="about-stat-value">88</span> suscriptores       </li>
Queriendo decir qué si ponemos esa string para que matchee en el preg_match_all, debería de darnos el resultado real:
Código
  1. preg_match_all('(<li class="about-stat">         <span class="about-stat-value">(.*)</span> suscriptores       </li>)', $result, $sus);



De momento sólo se me ocurre agregarle el salto de linea para evitar el preg_replace, quedando: -no me la llevo muy bien con las expresiones regulares, así que sale medio feo-
Código
  1. preg_match_all('(<li class="about-stat">([\n*])<span class="about-stat-value">(.*)</span> suscriptores)', $result, $sus);

Curioso cuanto menos, esa forma de conseguir el código en una linea sin problemas.

Muchísimas gracias por la ayuda, funciona perfectamente.

Un saludo!



Título: Re: Problemas con cURL
Publicado por: EFEX en 9 Enero 2014, 22:29 pm
Tambien con php se puede obtener, crear, modificar elementos DOM. Como por ejemplo la clase DOMDocument, pero no soporta atributos de tipo 'class=nombreClase' en vez tenes que utilizar DOMXPath para buscar cada clase y retornar la deseada, creo.

Pero por suerte existe otra clase Simple HTML DOM Parser, hasta utiliza selectores tal como jquery, muy util.

Código
  1. include_once('simple_html_dom.php'); //incluimos la clase
  2.  
  3. $result = '<li class="about-stat"><span class="about-stat-value">6</span>Subscribers</li>';
  4.  
  5. $html = str_get_html($result); //Crear elementos DOM a partir de un string tambien puede ser desde un sitio pero con file_get_html($html)
  6. $found =  $html->find('.about-stat-value', 0)->plaintext; //Buscamos el primer elemento con el atribudo class=about-stat-value y obtenemos su contenido
  7.  
  8. echo 'Suscriptores: ' . $found ;

http://simplehtmldom.sourceforge.net/
http://simplehtmldom.sourceforge.net/manual.htm