Поиск по блогу

воскресенье, 5 октября 2008 г.

Парсинг выдачи поисковиков. Определение позиции сайта. Часть I

Парсинг выдачи поисковиков — дело тонкое. Нехитрое, но тонкое.

Я думаю, что любой, кто начинал заниматься парсингом, — тренировался на поисковиках. Рассмотрим и мы эту задачу в качестве примера.

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

При написании программы всегда хочется сделать более-менее универсальную вещь. Однако известно, что каждый поисковик требует индивидуального подхода. Например, Яндекс проще было бы парсить через Яндекс XML, но там количество запросов без платного аккаунта ограничено. Но мы же все-таки просто тренируемся. Попробуем сделать простую программу, желательно с гибкой настройкой. Будем оперировать объектами.

У объекта "Поисковик" на первый взгляд должны быть свойства:
- название;
- шаблон get-запроса (с учетом возможности указания страницы);
- регулярное выражение для нахождения блока "сайт - сниппет" в выдаче поисковика.

Объявляем класс:
  TSearcher  = class
Name,
NextPageTmpl,
LinkRegExp : string;
end;

Информацию о поисковиках будем хранить в INI-файле. Положительные стороны использования INI-файлов при разработке программ я уже описывала: легкость перенастройки (без перекомпиляции), простота и наглядность. Считывать данные о поисковиках будем тем же методом, который я приводила при описании считывания данных об RSS-агрегаторах. Данные будут считываться при создании формы в список Searchers. В INI-файле будет также храниться информация о сайте и ключевых словах по умолчанию (как правило, для мониторинга своих сайтов мы используем один и тот же набор ключевиков, набирать которые каждый раз заново — нерационально).

procedure TfMain.actLoadINIExecute(Sender: TObject);
var
IniF : TIniFile;
KW,
sVal,
IniFName : string;
Sections,
SecParams,
SL : TStringList;
i : integer;
tmpSearch : TSearcher;
begin
IniFName := ExtractFilePath(Application.ExeName)+'/'+DefaultIniFileName;
if not FileExists(IniFName) then
begin
ShowMessage('Отсутствует ini-файл.');
exit;
end;

IniF := TIniFile.Create(IniFName);
edtSite.Text := iniF.ReadString('MAIN','DefSite',IniFName);
KW := iniF.ReadString('MAIN','DefWords','');

// вывод слов по умолчанию в Memo
SL := TStringList.Create();
ExtractStrings(['|'],[],PChar(KW),SL);
for i := 0 to SL.Count-1 do
Memo.Lines.Add(SL[i]);
SL.Free;

try
Sections := TStringList.Create();
try
// Читаем имена всех поисковиков
IniF.ReadSections(Sections);

// Перебираем имена секций и для секций с именами
// вида SITE создаем объекты
SecParams := TStringList.Create();
try
for i:=1 to Sections.Count do
begin
sVal := Sections[i-1];
if (Pos('SITE', sVal) = 1) and
(StrToIntDef(Copy(sVal, 5, Length(sVal)-4), -1)>0) then
begin
// Читаем параметры секции.
IniF.ReadSectionValues(sVal, SecParams);

if SecParams.Count > 0 then
begin
tmpSearch := TSearcher.Create;
tmpSearch.Name := SecParams.Values['Name'];
tmpSearch.NextPageTmpl := SecParams.Values['NextPageTmpl'];
tmpSearch.LinkRegExp := SecParams.Values['LinkRegExp'];
Searchers.Add(tmpSearch);
end
end;
end;
finally
SecParams.Free();
end;
finally
Sections.Free();
end;
except
end;
IniF.Free;
end;

procedure TfMain.FormCreate(Sender: TObject);
begin
Searchers := TList.Create;
actLoadINI.Execute;
actShowSearchersList.Execute;
end;

procedure TfMain.FormClose(Sender: TObject; var Action: TCloseAction);
var
i : integer;
begin
for i := 0 to Searchers.Count-1 do
TSearcher(Searchers[i]).Free;
Searchers.Free;
end;

procedure TfMain.actShowSearchersListExecute(Sender: TObject);
var
i : integer;
begin
// вывод инфы в TCheckListBox
for i := 0 to Searchers.Count-1 do
begin
SearchersList.AddItem(TSearcher(Searchers[i]).Name,Searchers[i]);
SearchersList.Checked[i] := true;
end;
end;


Интерфейс нашей программы будет примерно таким:
parser interface

Итак, по-моему, для первой части достаточно. О содержимом INI-файла подробнее поговорим в следующий раз.

Программируется гораздо быстрее, чем пишется описание процесса программирования. :)

Читайте окончание здесь.

Статьи схожей тематики:



Комментариев нет:

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

Комментарии модерируются, вопросы не по теме удаляются, троллинг тоже.

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

Поделиться