Foros del Web » Programando para Internet » PHP »

Ayuda para optimizar el rendimiento de este SIPDER

Estas en el tema de Ayuda para optimizar el rendimiento de este SIPDER en el foro de PHP en Foros del Web. Hola que tal? Acabo de hacer un sipder (va, en realidad encontré uno en un foro y lo adapté un poco a mis necesidades). Se ...
  #1 (permalink)  
Antiguo 17/03/2007, 08:41
 
Fecha de Ingreso: noviembre-2002
Mensajes: 73
Antigüedad: 21 años, 4 meses
Puntos: 0
Exclamación Ayuda para optimizar el rendimiento de este SIPDER

Hola que tal? Acabo de hacer un sipder (va, en realidad encontré uno en un foro y lo adapté un poco a mis necesidades). Se trata de un programa que dada una o unas URLs, las recorre extrayando las palabras de la página y los enlaces, y los almacena en una BD para luego poder realizar búsquedas.

Funciona muy bien, trabaja solamente dentro de los sitios web que se le insterten previamente, o sea si en la table enlaces insertaron "http://www.olimarvirtual.com", el programa va a examinar todas las páginas dentro de ese sitio web, y va a ignorar las URLs a otros sitios.

El único problema que veo es que cuando lo corro, el uso de la CPU de mi máquina queda al 100% dado que se realizan muchas operaciones con cadenas de caracteres. Me gustaría que alguien me ayudara a mejorar esto así lo puedo dejar corriendo mientras hago otras cosas, porque sinó mi máquina queda casi muerta.

El que quiera lo puede usar, y si lo puede mejorar agradezco publique las mejoras.

bot.php
Código PHP:
<? 
// BOT SpiderWeb PHP 
// by DeeRme 
// http://deerme.org 
include('class.mysql.php'); 
include(
'config.php'); 

function 
GetHTML($strURL)
{
    
$ch curl_init();
    
curl_setopt($chCURLOPT_REFERER"http://todo.com.uy/guia2.php3");
    
curl_setopt ($chCURLOPT_USERAGENT"Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
    
curl_setopt($chCURLOPT_RETURNTRANSFER,1);
    
curl_setopt($chCURLOPT_URL,$strURL);
    
$buffer curl_exec ($ch);
    
curl_close ($ch);
    unset(
$ch);
    return 
$buffer;
}

class 
bot 

    
// Variables 
    
var $url
    var 
$palabras
    var 
$enlaces
    var 
$html
    var 
$titulo

    
// Funciones 
     
    
function bot($url,$id
    { 
        global 
$servidor,$usuario,$password,$db,$hora_local,$url_aux
        if ( 
is_url($url,$id) ) 
        { 
            
// La URL esta Correcta 
            
$this->url=$url
            
// Abrimos la URL 
            
$leer fopen($url,"r"); 
            if (
$leer
            {       
                
$i='0'
                while( !
feof($leer) ) 
                { 
                    
$this->html $this->html fgets($leer); 
                    
$i++; 
                } 
                
fclose($leer); 

                
// Cerramos Punteros de la  URL 

                // Entregamos URL a la Funcion parse del HTML 
                
parse($this->html,$this->titulo,$this->palabras,$this->enlaces); 

                
// Ahora entregamos las Palabras a una Funcion 
                
$mysql = new mysql
                
$mysql->datos_conect($servidor,$usuario,$password); 
                
$mysql->connect(); 
                
$mysql->select($db); 
                
$sql="INSERT INTO md5search ( palabras , referer_id ) VALUES ('".$this->palabras."', $id)";     
                
$select $mysql->query($sql); 
                 
// Ahora entregamos las URL al a funcion 
                
guardar_url($this->enlaces,$url); 
            } 
        } 
    } 


function 
guardar_url(&$e,&$u

    
// Funcion que Guarda las URL en la BD si ya no está guardada
    
global $servidor,$usuario,$password,$db,$hora_local,$url_aux
    
$mysql = new mysql
    
$mysql->datos_conect($servidor,$usuario,$password); 
    
$mysql->connect(); 
    
$mysql->select($db); 

    for(
$i=0;$i<count($e);$i++) 
    { 
        if ( !
is_url$e[$i] ) ) 
        { 
            
// Transformamos URL 
            
$e[$i]=corregir_url($e[$i],$u); 
        } 
        
// Guardamos en la BD 
        
$sql="SELECT * FROM enlaces WHERE url='".$e[$i]."'"
        
$select $mysql->query($sql); 

        if ((
mysql_num_rows($select)==0)and(strpos($e[$i],$url_aux)===0))
        {
            
$sql="INSERT INTO `enlaces` ( `url` , `visitado` ) VALUES ( '".$e[$i]."', '0');"
            
$select $mysql->query($sql); 
            echo(
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Insertado: ".$e[$i]."<br>\n");                
        }
    } 




function 
corregir_url($e,$u

    
/* 
    /index.php 
    index.php 
    http://domo.com 
    http://domo.com/ 
    */ 
     
    // Vemos el Dominio 
    
if ( buscar_slash_final($u) ) 
    { 
         
// Quitamos el Slash del Dominio 
         
$u=substr($u,0,(strlen($u)-1)); 
    } 

    
// El Dominio sin Slash 
    // http://domo.com 

    
if (!buscar_slash_inicio($e) ) 
    { 
        
// Hay que Agregar Enlace 
        
$e='/'.$e
    } 
    
// Finalemente Devolvemos URL Correcta 
    
return ($u.$e); 


function 
buscar_slash_inicio($t

    if ( 
$t[0] == '/' 
    { 
        return(
1); 
    } 
    else 
    { 
        return(
0); 
    } 



function 
buscar_slash_final($t

    
$long=strlen($t); 
    if ( 
$t[($long-1)] == '/' 
    { 
        return(
1); 
    } 
    else 
    { 
        return(
0); 
    } 


function 
parse($html, &$title, &$text, &$anchors

  
$pstring1 "'[^']*'"
  
$pstring2 '"[^"]*"'
  
$pnstring "[^'\">]"
  
$pintag   "(?:$pstring1|$pstring2|$pnstring)*"
  
$pattrs   "(?:\\s$pintag){0,1}"

  
$pcomment enclose("--""-""->"); 
  
$pscript  enclose("<script$pattrs>""<""\\/script>"); 
  
$pstyle   enclose("<style$pattrs>""<""\\/style>"); 
  
$pexclude "(?:$pcomment|$pscript|$pstyle)"

  
$ptitle   enclose("<title$pattrs>""<""\\/title>"); 
  
$panchor  "<a(?:\\s$pintag){0,1}>"
  
$phref    "href\\s*=[\\s'\"]*([^\\s'\">]*)"

  
$html preg_replace("/$pexclude/iX"" "$html); 

  if (
$title !== false
    
$title preg_match("/$ptitle/iX"$html$title
             ? 
$title[1] : ''

  if (
$text !== false
  { 
    
$text preg_replace("/<$pintag>/iX",   " "$html);
    
$text preg_replace("/\\s+| /iX"" "$text);
  } 

  if (
$anchors !== false
  { 
    
preg_match_all("/$panchor/iX"$html$anchors); 
    
$anchors $anchors[0]; 

    
reset($anchors); 
    while (list(
$i$x) = each($anchors)) 
      
$anchors[$i] = 
        
preg_match("/$phref/iX"$x$x) ? $x[1] : ''

    
$anchors array_unique($anchors); 
  } 
   


function 
enclose($start$end1$end2

    return 
"$start((?:[^$end1]|$end1(?!$end2))*)$end1$end2"


/* 
function is_url($url) 

     return preg_match('#^http\\:\\/\\/[a-z0-9\-]+\.([a-z0-9\-]+\.)?[a-z]+#i', $url); 

*/ 

function is_url($url

    if ( 
substr_count($url'http://') == 
    { 
        return(
0); 
    }     
    else 
    { 
        return(
1); 
    } 


// Leemos URL en la Base de Datos 
$mysql = new mysql
$mysql->datos_conect($servidor,$usuario,$password); 
$mysql->connect(); 
$mysql->select($db); 

// está pensado para recorrer de a 100 enlaces no visitados por vez
for($j=0;$j<100;$j++)
{
    
$sql="SELECT * FROM `enlaces` WHERE `visitado` =0 ORDER BY `id` LIMIT 1 "
    
$select $mysql->query($sql); 
    
$row $mysql->f_array$select );
    echo (
"$j)Analiznado >>>>>>>>>>>>>>>> ".$row["url"]."<br>\n"); 
    
// Recorremos las URL 
    
if ( is_url($row['url']) ) 
    { 
        
// Lo marco como visitado.
        
$mysql2 = new mysql
        
$mysql2->datos_conect($servidor,$usuario,$password); 
        
$mysql2->connect(); 
        
$mysql2->select($db); 
        
$sql="UPDATE `enlaces` SET `visitado` = '1' WHERE `id` =".$row['id']." LIMIT 1 ;"
        
$select2 $mysql2->query($sql); 

        
// Si es URL Correcta entocnes la analizo
        // Extraigo el dominio en el que estoy y la guardo en $url_aux
        
$url_aux=str_replace("http://","",$row["url"]);
        
$url_aux="http://".substr($url_aux,0,strpos($url_aux,"/"));
        
$caca = new bot($row['url'],$row['id']); 
    } 
    else 
    { 
        
// Eliminamos URL 
        
$mysql2 = new mysql
        
$mysql2->datos_conect($servidor,$usuario,$password); 
        
$mysql2->connect(); 
        
$mysql2->select($db); 
        
$sql="DELETE FROM enlaces WHERE id=".$row['id']." LIMIT 1"
        
$select2 $mysql2->query($sql); 
    } 
}

?>

config.php
Código PHP:
<? 
$usuario
="root"
$password="xxxx"
$db="enlaces"
$servidor="localhost"
$hora_local=time(); 
$url_aux="";
?>
Esta es la estructura de la BD que se utiliza para almacenar los datos.

#
# Table structure for table enlaces
#

CREATE TABLE `enlaces` (
`id` bigint(11) NOT NULL auto_increment,
`url` varchar(255) NOT NULL default '',
`visitado` int(11) NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=139007 DEFAULT CHARSET=latin1;


#
# Table structure for table md5search
#

CREATE TABLE `md5search` (
`id` bigint(20) NOT NULL auto_increment,
`palabras` text,
`referer_id` bigint(20) NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=10471 DEFAULT CHARSET=latin1;
__________________
Marcelo :-)
música en mp3
Noticias de tecnología

Última edición por texe1; 17/03/2007 a las 08:50
  #2 (permalink)  
Antiguo 17/03/2007, 21:50
Avatar de DeeR  
Fecha de Ingreso: diciembre-2003
Ubicación: Santiago
Mensajes: 520
Antigüedad: 20 años, 4 meses
Puntos: 17
Re: Ayuda para optimizar el rendimiento de este SIPDER

Una recomendacion que yo le doy es
Cita:
ALTER TABLE `enlaces` ADD UNIQUE (
`url`
)
Ya que mi objetivo es capturar las palabras de un sitio, pero no lo quiero volver a visitarlo si de casualidad llegar a dar con la misma URL. por eso la dejo unique.

El consumo de CPU, es debido a que tiene que parsear el codigo HTML, capturando las palabras y las direcciones URL's , habria que mejorar dicha funcion.

La verdad yo no he tenido problema, lo tengo corriendo en un servidor hace ya como 3 semanas, y he capturado 126,586 palabras distintas ( 19.7 Mb ) y ha recorrido aldededor de 2353 web distintas :P , y no he tenido problema de consumo de CPU , el script consume mientras se esta ejecutando ( en mi caso, lo tengo para analizar 5 url en una ejecucion, se demora alrededor de 10sec) y esto lo tengo con un cron cada 2 min.


Asi que si quieres optimizarlo, la funcion principal, la parseadora, esa tienes que mejorar.

Yo no lo hago, por que me ha funcionado bien con mi proyecto md5search :P
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 13:56.