criar uma search engine
Precisei criar um mecanismo de busca para uma intranet e lembrei do final da década de 90 e os infinitos mecanismos de busca que apareciam e sumiam todo mês haha. Sistemas de buscas que pareciam definitivos como altavista.digital.com ou webcrawler.com, foram dando espaço para o Yahoo! e o hoje hegemônico Google. Lembro que tudo era feito com CGI(Common Gateway Interface) usando PERL… Sou preconceituoso contra PERL então sou suspeito para falar(hahahahaha) mas era engraçado, mil a uma linhas de código para adicionar e indexar paginas, fora a busca em sí. Hoje, com PHP, nao precisei nem de 60 linhas de código para fazer o mesmo(vai ver a culpa é do PERL hahahaha).
E é bem fácil, primeiro, precisamos de um banquinho de dados para facilitar a vida. Estou usando o MySQL porque ele está em todo lugar, mas voce pode usar até sqlite se quiser(e cheirar cola). Vou chamar minha base de dados de “busca”. Eu seu, sou criativo demais ;D
CREATE DATABASE `busca` USE `busca`; CREATE TABLE `searchengine` ( `id` INT NOT NULL AUTO_INCREMENT, `url` VARCHAR( 255 ) NOT NULL , `conteudo` TEXT NOT NULL , PRIMARY KEY ( `id` ) ) ENGINE = MYISAM
Bom, o objetivo não é ser tão eficiente quanto o googe, entao apenas salvo a url e o conteudo da pagina inicial para buscas posteriores, nada muito elaborado como contagem de palavras, etc.
Primeiro vamos criar um arquivo com as definiçoes de conexão com o banco e chamá-lo de banco.php:
<?php mysql_connect("localhost", "usuario", "senha"); mysql_select_db("busca"); ?>
Simples assim. Agora vamos criar a interface de adiçao de sites e chamá-lo de addurl.php:
<html><head><title>prototipo - busca</title></head><body> <form action="#" method="POST"> URL: <input type="text" name="url" size="50"><input type="submit" value="Add URL"> </form> <?php if(isset($_POST['url'])){ include('banco.php'); $url=$_POST['url']; if( substr($url,0,7) != "http://" ){ $url = "http://" . $url; } $pagedata = file_get_contents($url); $search = array( '@<script[^>]*?>.*?</script>@si', '@<style[^>]*?>.*?</style>@si', '@<[\/\!]*?[^<>]*?>@si', '@<![\s\S]*?--[ \t\n\r]*>@' ); $pagedata = preg_replace($search, '',$pagedata); $pagedata = str_replace("'","",$pagedata); mysql_query("INSERT INTO searchengine VALUES ('','$url','$pagedata')"); echo "URL Adicionada.<br><a href='./addurl.php'>Inicio...</a>"; } ?> </body></html>
como se pode ver, nao tem nada demais, apenas faz alguns ajustes na pagina, e o array $search contem os campos para cortar as tags html, scripts e css, para deixar o conteudo mais texto puro possivel. Obviamente o mesmo arquivo provê a lógica php para adicionar e o HTML de apoio. O ultimo passo é a interface de busca em sí. Vamos chama-la de index.php:
<html><head><title>prototipo - busca</title></head><body> <center> <form action="#" method="GET"> <b></b><input type="text" name="q" size="50"><input type="submit" value="Search"> </center> </form> <?php if(isset($_GET['q'])){ include('banco.php'); $sql = mysql_query("SELECT * FROM searchengine WHERE url LIKE '%$_GET[q]%' OR conteudo LIKE '%$_GET[q]%' LIMIT 0,20"); while($ser = mysql_fetch_array($sql)) { echo "<h2><a href='$ser[pageurl]'>$ser[pageurl]</a></h2>"; } echo '<a href="index.php">Voltar</a>'; } ?> </body></html>
É só isso? É sim haha. simples assim. Deste jeito está funcionando na intranet que escrevi.
Quando uma busca é feita, ele procura o texto na URL e no conteúdo da página inicial(por isto a necessidade de limpar os elementos html/script/css do documento). Não existe um rank, nem algoritmo inteligente de resposta, mas isso é facilmente implementável. Outra coisa é que isso mostrará apenas os primeiros 20 resultados devido a query sql “LIMIT 0,20”, porem é trivial fazr um count nos resultados e fazer um paginador, substituindo o 0,20 por qualquer resultado inicial e final.
Não dá para competir com o google ainda, mas é legal implementar em uma intranet e fazer um pré-parsing na query antes de chamar a pesquisa, para executar automaticamente algumas funçoes de conversão, e até de consulta de dados internos. Eu fiz isso antes do “include(‘banco.php’);”, se voce digitar “+funcionarios”, ele consulta a tabela de ponto e diz quantos estão trabalhando, ou “+agenda data”, mostra os compromissos globais para a data definida ou para o dia atual, caso nenhuma data seja definida. Defini todos os comandos para iniciar com “+” apenas para não pesar o parser, mas nada impede de usar um texto normal e passar por um parser mais sofisticado .
Fica a ideia.