Собственный поисковик: Поисковый робот

«Собственный поисковик: Поисковый робот» – 3 часть урока по созданию собственного поисковика, мы с вами создадим поисковый робот (crawler или spider), который будет заносить данные о проиндексированных страницах в нашу базу данных.
как сделать поисковик?
как сделать поисковый робот, паук, краулер, индексатор (spider, crawler)на Delphi?

Wikipedia: Поисковый робот («веб-паук», краулер) — программа, являющаяся составной частью поисковой системы и предназначенная для обхода страниц Интернета с целью занесения информации о них (ключевые слова) в базу поисковика. По своей сути паук больше всего напоминает обычный браузер. Он сканирует содержимое страницы, забрасывает его на сервер поисковой машины, которой принадлежит, и отправляется по ссылкам на следующие страницы. Владельцы поисковых машин обычно ограничивают глубину проникновения паука внутрь сайта и максимальный размер сканируемого текста, поэтому чересчур большие сайты могут оказаться не полностью проиндексированными поисковой машиной. Кроме обычных пауков, существуют так называемые «дятлы» — роботы, которые «простукивают» проиндексированный сайт, чтобы определить, что он подключен к Интернету.

Порядок обхода страниц, частота визитов, защита от зацикливания, а также критерии выделения ключевых слов определяется алгоритмами поисковой машины.

В большинстве случаев переход от одной страницы к другой осуществляется по ссылкам, содержащимся на первой и последующих страницах.

Также многие поисковые системы предоставляют пользователю возможность самостоятельно добавить сайт в очередь для индексирования. Обычно это существенно ускоряет индексирование сайта, а в случаях, когда никакие внешние ссылки не ведут на сайт, вообще оказывается единственной возможностью заявить о его существовании.

Ограничить индексацию сайта можно с помощью файла robots.txt, однако некоторые поисковые системы могут игнорировать наличие этого файла. Полная защита от индексации обеспечивается механизмами, обойти которые пока паукам не под силу. Обычно — установкой пароля на странице, либо требованием заполнить регистрационную форму перед тем, как получить доступ к содержимому страницы.

Кодим наш поисковый робот, который будет индексировать веб-страницы и готовить файл, для последующего импорта в индекс, которым поисковик будет пользоваться.

unit Main;interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, dTCPClient, IdHTTP;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Label1: TLabel;
ProgressBar1: TProgressBar;
IdHTTP1: TIdHTTP;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
stop:boolean;
t: cardinal;
dest:TStringList;

implementation

{$R *.dfm}

procedure DeleteLineBreaks(var src:string);
var
html:TStringList;
i:integer;
begin
html:=TStringList.Create;
html.Text:=src;
src:='';
for i:=0 to html.Count-1 do
src:=src+html.Strings[i];
html.Free;
end;

procedure ExtractHead(var src:string);
var
h1:integer;
s:string;
begin
s:=UpperCase(src);
h1:=pos('',s)+6;
src:=copy(src,h1,pos('',s)-h1);
end;

function GetTitle(var src:string):string;
var
t1:integer;
s:string;
begin
s:=UpperCase(src);
t1:=pos('',s)+7;
result:=StringReplace(copy(src,t1,pos('',s)-t1),'"','"',[rfReplaceAll]);
end;

procedure ExtractMeta(var src:string);
var
m1,m2:integer;
s,tmp:string;
begin
s:=UpperCase(src);
tmp:=s;
src:='';
m1:=pos('0 do
begin
m2:=pos('>',s);
src:=src+copy(tmp,m1,m2-m1+1)+#13#10;
Delete(s,1,m2);
Delete(tmp,1,m2);
m1:=pos('0 then
begin
tmp:=html.Strings[i];
m:=pos('CONTENT',s);
Delete(tmp,1,m+7);
m:=pos('"',tmp);
Delete(tmp,1,m);
m:=pos('"',tmp);
result:=StringReplace(copy(tmp,1,m-1),'"','"',[rfReplaceAll]);
break;
end;
end;
end;

procedure Execute(p: pointer);
var
list:TStringList;
i:integer;
s,d,k,t:string;
begin
list:=TStringList.Create;
list.LoadFromFile('urls.txt');
dest.Clear;
Form1.Label1.Caption:='Info: '+inttostr(list.Count)+' sites.';
Form1.ProgressBar1.Max:=list.Count;
for i:=0 to list.Count-1 do
try
if stop then break;
s:=Form1.IdHTTP1.Get(list.Strings[i]);
Form1.ProgressBar1.Position:=i+1;
DeleteLineBreaks(s);
ExtractHead(s);
t:=GetTitle(s);
ExtractMeta(s);
d:=GetMetaData('description',s);
k:=GetMetaData('keywords',s);
dest.Add('INSERT INTO base(url,title,description,keywords) VALUES ("'+list.Strings[i]+'","'+t+'","'+d+'","'+k+'");');
except
Form1.ProgressBar1.Position:=i+1;
Continue;
end;
list.Free;
Form1.ProgressBar1.Position:=0;
Form1.Button2.Enabled:=false;
Form1.Button1.Enabled:=true;
ExitThread(0);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
stop:=false;
Button1.Enabled:=false;
Button2.Enabled:=true;
createthread(nil, 128, @Execute, self, 0, t);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
stop:=true;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
dest:=TStringList.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
dest.Free;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
dest.SaveToFile('base.txt');
end;

end.

Вот такой вот код мы должны не просто написать, а понять как он работает, чтобы еще добавить пару фишек для своего собственного. Например, добавить еще несколько потоков для обработки большего количества страниц за короткое время. У меня тут 2 потока: основной и процедура которая непосредственно подключается к сайту и читает мета теги description, keywords, title + ваши собственные варианты (h1, h2, h3, h4, h5, h6, strong, b, em, i и т.д.)
Пишем поисковый робот

Сначала открываем Delphi, в новой форме ставим 3 кнопки Button, 1 ProgressBar, 2 Label’а, 1 idHTTP

В колонке слева (TreeView) выбираем нашу форму, далее в инспекторе объектов открываем вкладку Events и там где OnCreate – двойной щелчок на выпадающее меню справа, должна создастся новая процедура в котором пишем dest:=TStringList.Create;
procedure TForm1.FormCreate(Sender: TObject);
begin
dest:=TStringList.Create;
end;

для Button1 таким же способом заходим в OnClick и вставляем этот код
procedure TForm1.Button1Click(Sender: TObject);
begin
stop:=false;
Button1.Enabled:=false;
Button2.Enabled:=true;
createthread(nil, 128, @Execute, self, 0, t); // создание потока
end;

Первая кнопка создает поток

таким же способом делаем код для второй кнопки
procedure TForm1.Button2Click(Sender: TObject);
begin
stop:=true;
end;

Этот код останавливает поток.
Form1->Events-OnDestroy
procedure TForm1.FormDestroy(Sender: TObject);
begin
dest.Free;
end;

Кнопка сохраняющая текстовый файл, который и является запросом в базу данных MySQL – импортирует проиндексированные данные
procedure TForm1.Button3Click(Sender: TObject);
begin
dest.SaveToFile('base.txt');
end;

Самое главное: Сердце поискового робота
procedure Execute(p: pointer);
var
list:TStringList;
i:integer;
s,d,k,t:string;
begin
list:=TStringList.Create;
list.LoadFromFile('urls.txt');
dest.Clear;
Form1.Label1.Caption:='Info: '+inttostr(list.Count)+' sites.';
Form1.ProgressBar1.Max:=list.Count;
for i:=0 to list.Count-1 do
try
if stop then break;
s:=Form1.IdHTTP1.Get(list.Strings[i]);
Form1.ProgressBar1.Position:=i+1;
DeleteLineBreaks(s);
ExtractHead(s);
t:=GetTitle(s);
ExtractMeta(s);
d:=GetMetaData('description',s); //вызывает функция GetMetaData
k:=GetMetaData('keywords',s); //вызывает функция GetMetaData
dest.Add('INSERT INTO base(url,title,description,keywords) VALUES ("'+list.Strings[i]+'","'+t+'","'+d+'","'+k+'");'); //готовит файл импорта
except
Form1.ProgressBar1.Position:=i+1;
Continue;
end;
list.Free;
Form1.ProgressBar1.Position:=0;
Form1.Button2.Enabled:=false;
Form1.Button1.Enabled:=true;
ExitThread(0);
end;

Процедура подключающаяся к веб-страницу, точнее берущее у сервера html-код и “выдергивающая” оттуда значение тегов description, title, keywords.

Следующая процедура DeleteLineBreaks, она записывает html-код в одну строку для удобства.
procedure DeleteLineBreaks(var src:string);
var
html:TStringList;
i:integer;
begin
html:=TStringList.Create;
html.Text:=src;
src:='';
for i:=0 to html.Count-1 do
src:=src+html.Strings[i];
html.Free;
end;

Так как наши теги находятся в тегах мы оставляем только их содержимое.
procedure ExtractHead(var src:string);
var
h1:integer;
s:string;
begin
s:=UpperCase(src);
h1:=pos('',s)+6;
src:=copy(src,h1,pos('',s)-h1);
end;

Функция берет имя веб-страницы, т.е. значения между тегами
function GetTitle(var src:string):string;
var
t1:integer;
s:string;
begin
s:=UpperCase(src);
t1:=pos('',s)+7;
result:=StringReplace(copy(src,t1,pos('',s)-t1),'"','"',[rfReplaceAll]);
end;

Оставляем только мета теги.
procedure ExtractMeta(var src:string);
var
m1,m2:integer;
s,tmp:string;
begin
s:=UpperCase(src);
tmp:=s;
src:='';
m1:=pos(' while m10 do
begin
m2:=pos('>',s);
src:=src+copy(tmp,m1,m2-m1+1)+#13#10;
Delete(s,1,m2);
Delete(tmp,1,m2);
m1:=pos(' end;
end;Функция берущая значения тегов description и keywords, смотря с каким атрибутом она была запущена.
function GetMetaData(const data:string; var src:string):string;
var
html:TStringList;
i,m:integer;
s,tmp:string;
begin
html:=TStringList.Create;
html.Text:=src;
for i:=0 to html.Count-1 do
begin
s:=UpperCase(html.Strings[i]);
if pos(UpperCase(data),s)0 then
begin
tmp:=html.Strings[i];
m:=pos('CONTENT',s);
Delete(tmp,1,m+7);
m:=pos('"',tmp);
Delete(tmp,1,m);
m:=pos('"',tmp);
result:=StringReplace(copy(tmp,1,m-1),'"','"',[rfReplaceAll]);
break;
end;
end;
end;
Вот и все! Наш поисковый робот написан. Он будет использовать urls.txt в качестве базы урлов веб-страниц. А созданный текстовый файл base.txt будет использоватся для импорта в Индекс.Если есть вопросы пишите в комментах.

Скачать Поисковый робот на Delphi

]]>

Добавить в закладки

]]>

Теги: , ,

10 комментариев по “Собственный поисковик: Поисковый робот”

  1. ]]> Как добыть трафик для своего сайта? ]]> сказал:
    июля 21, 2009 в 02:13

    [...] день! Чтобы образовалась целевая аудитория сайта. Поисковые системы любят постоянно обновляемые сайты, не надо трудится [...]

  2. ]]> ]]> сказал:
    июля 27, 2009 в 00:19

    а чего робот на дельфях?
    нет чтоб на перле, чтоб на *NIXах работало все..

  3. ]]> василий ]]> сказал:
    декабря 1, 2009 в 04:37

    t1:=pos(”,s)+7; result:=StringReplace(copy(src,t1,pos(”,s)-t1),’”‘,’”‘,[rfReplaceAll]);
    ——————————————–
    я так понимаю здесь какая-то опечатка? разъясните, плиз, сей момент

  4. ]]> василий ]]> сказал:
    декабря 1, 2009 в 04:44

    в файле отчета выводит только адреса просмотренных сайтов. поле title и другие пустуют(((((

  5. ]]> Admin ]]> сказал:
    декабря 2, 2009 в 23:42

    Василий,
    1) скачайте приложеннай проект на Delphi, посмотрите исходники. Код, который вы привели, нужен для копирования URL’а
    2) в том файле должны быть урлы, которые должны быть просканированы

  6. ]]> Сергей. Webypoki СУПЕР САЙТ!!!! ]]> сказал:
    декабря 11, 2009 в 02:15

    Скажите пожалуйста, что делать после того, как страницы были проиндексированы? Я создал поисковик на Ucoz.

  7. ]]> ]]> сказал:
    декабря 11, 2009 в 02:17

    Скажите что делать после того как робот проиндексировал страницы??

  8. ]]> ]]> сказал:
    марта 19, 2010 в 00:55

    Благодарен за листинг. Люблю Делфи ))

  9. ]]> ]]> сказал:
    марта 19, 2010 в 01:18

    Я нигде не увидел поиск ссылок в теле HTML-страницы, ну и переход по ним. Хотя, в принципе, регулярные выражения сотворят чудеся.

    Представленный выше исходник, на мой взгляд, больше похож на тривиальный парсер, нежели на поискового паука.

  10. ]]> ]]> сказал:
    апреля 8, 2010 в 00:33

    Хм.. я обязательно попробую

Оставьте комментарий: