Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   PHP (https://www.clubdelphi.com/foros/forumdisplay.php?f=15)
-   -   Comprobar si un enlace (URL) sigue siendo válido (https://www.clubdelphi.com/foros/showthread.php?t=36651)

dec 19-10-2006 15:33:04

Comprobar si un enlace (URL) sigue siendo válido
 
Hola,

La idea es sencilla, aparentemente: cómo averiguar si un enlace, una URL, lleva al recurso que se supone tiene que llevar, esto es, cómo averiguar que un enlace no está roto, como suele decirse.

He encontrado varias soluciones que pasan por las funciones "fopen", "fsockopen" de PHP de una forma más o menos prolija; he dado con muy aparente Cliente HTTP que podría acaso servir para el caso...

Pero, resulta que lo que más confianza me ofrece, que es el Cliente HTTP mencionado, ni siquiera tratando de recuperar sólo el "estado" de la petición "HTTP GET" me termina de convencer del todo.

¿Por qué? Pues porque se trataría de comprobar "cada vez" (porque sería una tarea que podría llevarse a cabo varias veces incluso al mismo tiempo, por varios usuarios) y, tras probar el asunto en mi "Servidor local", da la impresión de que todo el sistema se resiente.

Esto es, tengo miedo de hacer algo así en el Servidor "en producción", puesto que no quiero causar problemas en el mismo, saturarlo, recargarlo, etc. Entonces, me pregunto si no existirá de comprobar si un determinado enlace sigue siendo válido o no.

No sé. Es que se me ocurre que ya no es que el Servidor tenga que realizar la petición "HTTP GET", y esto, en un bucle de "cienes" de enlaces pueda causarle algún mal trago, sino que la propia petición "HTTP GET" tiene que llevarse a cabo (vaya perogrullada), es decir, no es posible evitar ese "a ver que voy... espera un momento... ya estoy aquí".

Esa comunicación tiene que darse entre un sistema y otro, con el fin de averiguar lo que se solicita, de darle la oportuna respuesta al encargo, pero, ¿no habrá otra manera de hacerlo? ¿tiene que ser obligatoriamente vía HTTP? Vosotros que sabéis de esto, ¿no podría hacerse un "ping" de esos? ¿Valdría algo así?

Supongo que he dicho una estupidez como una casa. Primero porque me parece que si el enlace, la URL a comprobar, se inicia con un "http://"... parece pensar en lo excusado que pueda hacerse nada sin usar dicho protocolo, pero, para qué nos vamos a engañar, yo de esto no es que sepa mucho...

También me extraña no haberme encontrado, luego de buscar varias veces por Internet, ningún otro método sino los mencionados que se basan en las funciones "fopen", etc. Así que... a lo peor es que tiene que ser así y no hay tu tía, como se dice.

Bueno. Muchas gracias de antemano por vuestras sugerencias, comentarios e ideas, que serán todas bienvenidas, como no podía ser de otra manera. ;)

kayetano 19-10-2006 15:53:11

Hola

Yo uso fopen.
Se me ocurren algunas soluciones a tu problema:

1. Lo que puedes hacer es comprobar el enlace cuando se intenta entrar, si no existe ya lo marcas como eliminado y ya no aparecerá más, mientras tanto lo tienes como activo.
2. Otra opción es controlar el estado del enlace periodicamente, por ejemplo con un CRON que se lance todas las mañanas.
3. Y otra solución que se me ocurre es fecha los enlace y definir un periodo de caducidad, una vez superado ese periodo, el primer usuario que lo consulte comprueba si existe y se vuelve a fecha para evitar que el siguiente usuario vuleva a realizar la comprobación.

Efectivamente intentar controlar el estado de todos (o muchos) enlaces a la vez y por todos los usuarios es una animalada.

seoane 19-10-2006 15:55:56

A lo mejor estoy diciendo una tontería, pero por que en vez de comprobar los enlaces cada vez que se solicita la pagina, no creas un proceso que se ejecute a su aire y que este continuamente comprobando los enlaces de la base de datos, no hace falta que que este proceso tenga mucha prioridad para así no interferir con el resto de procesos del servidor. Cuando este encuentre un enlace no valido, lo marcaría en l base de datos. Así cuando se solicitara una pagina se podría saber si el enlace sigue siendo valido.

No es una solución en tiempo real, a lo mejor un enlace puede dejar de ser valido y no enterarte hasta horas después cuando le toque ser comprobado, pero no creo que el beneficio de comprobar los enlaces en tiempo real compense la carga de trabajo para el servidor que eso supone.

En cuanto a lo de comprobar un enlace sin usar http, lo veo difícil. Con un "ping de esos", como tu los llamas, solo puedes comprobar que el nombre del dominio es correcto y que el servidor esta funcionando, pero no si un determinado documento ha sido borrado. Además una simple petición HEAD para saber si el documento todavía existe no debería de consumir mucho tiempo.

Bueno, ahí te dejo mis divagaciones, pues en realidad no te aporte nada tangible :)

dec 19-10-2006 16:13:12

Hola,

Pues muchas gracias a ambos por vuestras sabias y rápidas respuestas.

Cita:

Empezado por Kayetano
Se me ocurren algunas soluciones a tu problema:

1. Lo que puedes hacer es comprobar el enlace cuando se intenta entrar, si no existe ya lo marcas como eliminado y ya no aparecerá más, mientras tanto lo tienes como activo.

Sí; efectivamente era lo que se me había ocurrido a mí también. Concretamente, la aplicación de la que hablamos (Loturak) lleva actualmente una cuenta de las visitas a cada uno de los enlaces.

En el momento en que un enlace va a visitarse se incrementa su "contador de visitas" y es en este momento en donde, antes de abrir el enlace en cuestión (como se hace actualmente) podría comprobarse su existencia y plantear al usuario el oportuno "diálogo" en caso de topar con un enlace "roto".

Cita:

Empezado por Kayetano
2. Otra opción es controlar el estado del enlace periodicamente, por ejemplo con un CRON que se lance todas las mañanas.

Bueno. La tarea que pretendía llevar a cabo no era que fuera a llevarse a cabo por parte de la aplicación como una tarea de administración o algo así. Se trataría (se pensaba) dar al usuario la posibilidad de comprobar si sus enlaces (los que él guarda en la aplicación) seguían siendo válidos o no.

Lo que comentas podría ser una opción, pero, me parece que vamos a apañarnos siguiendo el punto número 1... aunque,... el siguiente punto nos ha dado alguna idea...:

Cita:

Empezado por Kayetano
3. Y otra solución que se me ocurre es fecha los enlace y definir un periodo de caducidad, una vez superado ese periodo, el primer usuario que lo consulte comprueba si existe y se vuelve a fecha para evitar que el siguiente usuario vuleva a realizar la comprobación.

Aquí pienso si sería bueno, en lugar de comprobar todos los enlaces (que se visiten, y cuando se visiten), podrían comprobarse aquellos que ya tuvieran un determinado tiempo añadidos en la base de datos de la utilidad. Puede ser un buen punto, puesto que, aunque no se visitan enlaces "constantemente", lo cierto es que de este modo reduciríamos un tanto la "carga" que pudiera conllevar la tarea que nos ocupa.

Son buenas idas Kayetano. Muchas gracias. :)

Cita:

Empezado por Domingo
En cuanto a lo de comprobar un enlace sin usar http, lo veo difícil. Con un "ping de esos", como tu los llamas, solo puedes comprobar que el nombre del dominio es correcto y que el servidor esta funcionando, pero no si un determinado documento ha sido borrado.

Estás completamente en lo cierto Domingo. Era lo que suponía, pero, dicho como lo has dicho queda mucho más claro y me queda si cabe mucho más claro a mí también, que falta me hace. ;)

Cita:

Empezado por Domingo
Bueno, ahí te dejo mis divagaciones, pues en realidad no te aporte nada tangible

Huy, no creas, precisamente, donde menos te percatas salta la liebre... :D :D

Muchas gracias a todos. Creo que al cabo tomaré la determinación que se ha comentado: comprobaremos los enlaces el momento en que estos vayan a ser visitados, abiertos, y, no en todos los casos, sino únicamente si el enlace puede considerarse "antiguo" en función de su fecha de inserción en la base de datos.

¡Gracias otra vez! :D

dec 19-10-2006 19:03:07

Hola,

Bueno. Pues ya está. No del todo, porque al cabo no estamos utilizando la fecha del enlace, pero, la cosa va bastante "rápida" y bien, puesto que hemos procurado utilizar el Cliente HTTP muy básicamente: únicamente requerimos la cabecera HTTP del recurso (enlace), no nos quedamos con "Cookies", ni con "refererers", etc.

Este es el método que hemos añadido a la clase "ValidarEx" conque contamos en la aplicación:

Código PHP:

  function VisitaEnlace($urlEnlace)
  {
      if(!
parse_url($urlEnlace))
        return 
false;

    
$datosUrl parse_url($urlEnlace);

    
$host '';
    if(isset(
$datosUrl['host']))
      
$host $datosUrl['host'];

    
$path '/';
    if(isset(
$datosUrl['path']))
      
$path $datosUrl['path'];

    
$puerto 80;
    if(isset(
$datosUrl['port']))
      
$puerto $datosUrl['port'];

    
$agente 'Loturak v'.APP_VERSION.' (' .APP_DOMINIO_WEB')';

    require(
'httpclient.class.php');
    
$http = new HttpClient($host$puerto);
    
$http->setDebug(false);
    
$http->setMaxRedirects(5);
    
$http->setHeadersOnly(true);
    
$http->setUserAgent($agente);
    
$http->setPersistCookies(false);
    
$http->setHandleRedirects(true);
    
$http->setPersistReferers(false);
    
$http->get($path);

    return (
$http->getStatus() == 200);
  }

// Es decir, utilizamos la función tal que así:

$urlEnlace 'http://www.unenlace.es';
if(!
ValidarEx::VisitaEnlace($urlEnlace))
{
  
XHtml::ErrorVisitandoEnlace($urlEnlace);
  die;


La cosa funciona más o menos así: http://www.loturak.es/visitar?enlace-id=4386

¿Porqué no hemos utilizado la función "fopen"? Bueno... nos parece que lo que nos ofrece el Cliente HTTP nos interesa: por lo pronto se encargará de redirigir a los usuarios al enlace correcto, en caso de que las cabeceras HTTP de la petición que se lleva a cabo así lo indique.

¿Qué os parece del asunto? :)

roman 20-10-2006 17:33:41

Una pregunta, ¿esto que hace el cliente http que usas, no puede hacerse con Ajax?

// Saludos

dec 20-10-2006 17:54:10

Hola,

Cita:

Empezado por Román
Una pregunta, ¿esto que hace el cliente http que usas, no puede hacerse con Ajax?

No hay necesidad,... ¿no? La comprobación del enlace se lleva a cabo justo cuando se va a visitar, es decir, si el enlace no está roto en realidad el usuario "sale de la aplicación".

Queda, es cierto, el tema de la "vista previa" del enlace que existe en Loturak. En este caso sí que podríamos considerar utilizar una llamada HTTP en segundo plano para comprobar si un determinado enlace existe, puesto que el usuario "se queda" en la aplicación.

roman 20-10-2006 18:05:45

Cita:

Empezado por dec
No hay necesidad,... ¿no?

Supongo que no.

// Saludos


La franja horaria es GMT +2. Ahora son las 08:31:38.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi