уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Итак, в начале коротко о последних событиях в блоге.

Первое событие — у блога появился новый автор — SeregaAltmer, так что теперь я не одинок :). Первый пост нового автора Вы можете прочитать уже сейчас.

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

Второе событие, которое я, признаться не ожидал, заключается в том, что в ближайшее время будет разработана новая версия «Хронометра» с учетом всех предложений, пожеланий и баг-репортов. Так что, если у Вас есть что предложить по поводу программы — милости прошу в тему или пишите на email — vlad383@mail.ru.  Вообще программа создавалась «под себя» и отчасти ради интереса «смогу или нет», но раз есть интерес к продукту — будем развивать дальше. Ну, а теперь по теме топика. Сегодня рассмотрим новый компонент для Delphi 2010 — SearchCatalogs, который предназначен для определения нахождения сайта в каталогах: Яндекс.Каталог, DMOZ и Yahoo Directory — трех крупнейших каталогах сайтов в Интернет. Думаю, что подобный компонент будет очень кстати разработчикам программ по аудиту сайтов.

1.  Пара слов о поиске в каталогах.

В начале рассмотрим простой вопрос — как вообще проводится поиск в каталогах. Провести поиск вручную проблем не составит ни для кого — ввел URL в поле поиска, нажал кнопку — получил результат. А программно?  Естественно при программном поиске сайта в каталогах не обойдется без применения RegExp и регулярных выражений. Можно было бы, конечно, поковыряться в DOMе, по-вытаскивать необходимые теги, по-разбирать содержимое и т.д., но на мой взгляд, это лишнее и можно обойтись более простыми способами.  Достаточно знать URL страницы с результатами поиска каталога и применить RegExp и дело в шляпе. Рассмотрим как это можно сделать на примере выбранных каталогов.

Яндекс.Каталог

Заходим в каталог и записываем в поле поиска любой сайт, например webdelphi.ru, жмем поиск и получаем следующий результат:

yacaКак видите блог отсутствует в каталоге. Какую информацию мы можем вытащить с этой странички? Я думаю, что если функция поиска будет работать «от противного», т.е. определять отсутствие сайта в каталоге, то здесь можно воспользоваться titl’ом странички, который кстати сказать довольно просто вытаскивается со страницы хоть через TWebBrowser, хоть напрямую из DOM, хоть с помощью RegExp:

<title>Яндекс.Каталог:webdelphi.ru (0)</title>

То есть вытаскиваем титл, читаем число скобках и, если число отлично от нуля, то сайт находится в каталоге.  Можно воспользоваться и другими способами, например искать не число в скобках, а подстроку, которая выдается на странице поиска в том случае, если сайт обнаружен в Яндекс.Каталог. Регулярное выражение для этого случая может быть таким:

'.*(?:сайт).*?(d+)'

SearchCatalogs работает с Яндекс.Каталогом именно с помощью этого регулярного выражения. Какой из способов будет удобно использовать Вам, в случае самостоятельной работы с этим каталогам решать Вам, мне остается только сказать, что URL необходимой для работы странички Яндекс.Каталога выглядит вот так (для использования в Delphi):

'http://search.yaca.yandex.ru/yandsearch?text=%s&&rpt=rs2';

Вместо %s подставляете домен и можете качать страничку результатов поиска.

DMOZ

Строка URL страницы результатов поиска для DMOZ выглядит следующим образом:

'http://search.dmoz.org/cgi-bin/search?search=%s

В случае, если сайт не найден в каталоге, страничка будет снаружи выглядеть вот так:

dmozНа рисунке также отмечена подстрока, которую можно искать для определения нахождения сайта в каталоге.

Единственное, что немного осложняет поиск — наличие гиперссылки в подстроке. Но мы же знаем (или делаем вид, что знаем), что такое RegExp! Составляем простенькое регулярное выражение:

'.*?No.*?results.*?found'

То есть ищем подстроку в которой встречаются подстроки No, Results, found, разделенные любыми другими символами. В нашем случае этими «любыми» символами будет как раз html-код ссылки. Нашли подстроку — значит сайта в каталоге нет.

Yahoo Directory

Целевой URL:

'http://search.yahoo.com/search/dir?p=%s'

При работе с Yahoo Directory, также как и с DMOZ наиболее целесообразно парсить страничку на предмет отсутствия сайта в каталоге.
Смотрите как красиво и просто выглядит целевая подстрока:

No Directory Search results were found.

Здесь даже RegExp не нужен — поискали соответствие в тексте тем же pos() и все становится предельно ясно.

С поиском разобрались. А теперь переходим непосредственно к компоненту.

2. Свойства, методы и события компонента SearchCatalogs

У компонента SearchCatalogs определены следующие свойства:

Domain: string — домен для проверки наличия в каталогах.

Options — группа из трех свойств:

  • Yandex: boolean — определять наличие сайта в Яндекс.Каталог
  • YahooDir: boolean — определять наличие сайта в Yahoo Directory
  • DMOZ: boolean — определять наличие сайта в DMOZ

Active: boolean — свойство «только для чтения» определяет выполняются ли в текущий момент какие либо операции в компоненте.

А также три свойства для чтения:

InYandex: boolean — если true, то сайт находится в Яндекс.Каталоге

InDMOZ: boolean — то же самое, но для DMOZ

InYahoo: boolean — то же самое для Yahoo Directory.

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

Соответственно, для прерывания работы используется второй метод — Deactivate.

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

Для того, чтобы отслеживать ход выполнения всех операций в SearchCatalogs реализованы следующие события:

OnStartYandex — был запущен поток для Яндекса
OnStartDMOZ — был запущен поток для DMOZ
OnStartYahooDir — был запущен поток для Yahoo Directory

OnGiveYandex — успешно получены данные о сайте в Яндекс.Каталоге
OnGiveDMOZ — успешно получены данные о сайте в DMOZ
OnGiveYahoo — успешно получены данные о сайте в Yahoo Directory

OnStopYandex — работа потока Яндекса прервана
OnStopDMOZ — работа потока DMOZ прервана
OnStopYahooDir — работа потока Yahoo прервана

OnAcceptData — были успешно получены данные от одного или нескольких потоков. Событие удобно использовать для вывода информации «на лету».

Конечно, подобное количество копипаста может быть лишним. Например все эти события можно было ужать всего в три-четыре штуки, но вот такой вот я разгильдяй, люблю копипастить собственный код :) Да и по-моему, так проще отследить каждый поток в отдельности.

Так как про установку компонентов для Delphi 2010 я уже писал не один раз, то не буду повторяться и переходим сразу к реализации тестового приложения с использованием компонента.

3. Пример работы компонента SearchCatalogs

Заготовка для будущего приложения у меня получилась следующая:

использование компонента Delphi searchcatalogsВсё предельно просто (тем более, что это просто пример, а не продукт для реализации за деньги через интернет) — одно поле ввода для домена, две кнопки одна из которых запускает компонент в работу, а вторая прерывает потоки и куча label’ов для вывода информации. Для включения/выключения опций предусмотрены три чекбокса.

Работать приложение будет следующим образом — записываем в поле адрес домена, выбираем необходимые каталоги, жмем кнопку и покорно ждем результат или прерываем потоки, если терпение лопнуло или возникли проблемы с Интернет-соединением.

Листинг всей программы также прост как и интерфейс (привожу только обработчики событий):

procedure TForm1.Button1Click(Sender: TObject);
begin
  SearchCatalogs1.Domain:=Edit1.Text;
  Edit1.Text:=SearchCatalogs1.Domain;
  SearchCatalogs1.Options.Yandex:=CheckBox1.Checked;
  SearchCatalogs1.Options.DMOZ:=CheckBox2.Checked;
  SearchCatalogs1.Options.YahooDir:=CheckBox3.Checked;
  SearchCatalogs1.Activate;
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  SearchCatalogs1.Deactivate;
end;
 
procedure TForm1.SearchCatalogs1AcceptData(InYandex, InDMOZ,
InYahooDir: Boolean);
begin
  SearchCatalogs1GiveDMOZ(InDMOZ);
  SearchCatalogs1GiveYahoo(InYahooDir);
  SearchCatalogs1GiveYandex(InYandex);
end;
 
procedure TForm1.SearchCatalogs1GiveDMOZ(InDMOZ: Boolean);
begin
if InDMOZ then
  label8.Caption:='есть'
else
  label8.Caption:='нет';
label5.Caption:='отработал';
end;
 
procedure TForm1.SearchCatalogs1GiveYahoo(InYahooDir: Boolean);
begin
if InYahooDir then
  label9.Caption:='есть'
else
  label9.Caption:='нет';
label6.Caption:='отработал';
end;
 
procedure TForm1.SearchCatalogs1GiveYandex(InYandex: Boolean);
begin
if InYandex then
  label7.Caption:='есть'
else
  label7.Caption:='нет';
label4.Caption:='отработал';
end;
 
procedure TForm1.SearchCatalogs1StartDMOZ;
begin
  label5.Caption:='запущен'
end;
 
procedure TForm1.SearchCatalogs1StartYahooDir;
begin
  label6.Caption:='запущен'
end;
 
procedure TForm1.SearchCatalogs1StartYandex;
begin
  label4.Caption:='запущен'
end;
 
procedure TForm1.SearchCatalogs1StopDMOZ;
begin
  label5.Caption:='остановлен'
end;
 
procedure TForm1.SearchCatalogs1StopYahooDir;
begin
  label6.Caption:='остановлен'
end;
 
procedure TForm1.SearchCatalogs1StopYandex;
begin
  label4.Caption:='остановлен'
end;

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

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
11 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
evgen
evgen
04/11/2009 16:51

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

Evgeniy
Evgeniy
05/11/2009 03:22

Запускаю все на Embarcadero RAD Studio 2010
Мне требуются в одном проекте чтобы работало:
SearchCatalogs
searchstats
DomainAge
Получается работает только один из компонентов, второй и третий не ставяться,  одновременно с первым, по отдельности все ок.
 
П.С в searchstats не работает парсер рамблера, еще читал где то что ты писал как получить PR сайта от гугла, но так и не получилось сделать как в твоей заметке, не мог бы ты добавить это в компонент yatic

Evgeniy
Evgeniy
05/11/2009 10:59

Я так подумал что из за того что во всех пакетах есть одинаковый файл, на него и ругается, что уже используется: InetThread
про рамблер не парсит если страниц в нем больше 1000, скорее всего из за пробела который там, например в индексе 1 500 страниц и ошибка строковая.
 
Спасибо, жду решений =)

Evgeniy
Evgeniy
06/11/2009 12:22

Отлично буду ждать, что получилось…

Evgeniy
Evgeniy
08/11/2009 05:54

Спасибо, все встало, единственно не работает рамблер, если страниц до 1000 то все ок, если больше он определяет 4 страницы вместо 4000 или 1 вместо 1500

Evgeniy
Evgeniy
08/11/2009 08:15

Можешь еще подсказать, каким образом лучше всего организовать массовую проверку параметров? в цикле получается, но параметров не один, не могу разобраться? Не будет ли бана за такое?