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.