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

вторник, 31 марта 2009 г.

Компоненты Internet Direct (Indy). Вводная статья для новичков

Если в двух словах, Indy — компоненты для удобной работы с популярными интернет-протоколами. Принцип их работы основывается на использовании сокетов в блокирующем режиме. Indy интересен и удобен тем, что достаточно сильно абстрагирован. И программирование в Indy сводится к линейному программированию. Кстати, в интернете широко распространена переводная статья, в которой есть слова "блокирующий режим не является дьяволом" :)) В свое время меня очень позабавил этот перевод. Статья — часть книги Хувера и Харири "Глубины Indy". В принципе, для работы с Indy вам вовсе не обязательно всю ее читать, но ознакомиться с принципами работы протоколов интернета я все-таки рекомендую. Что касается "дьявольского" режима. Вызов блокирующего сокета действительно не возвращает управления, пока не выполнит свою задачу. Когда вызовы делаются в главном потоке, интерфейс приложения может "подвиснуть". Чтобы позволить избежать этой неприятной ситуации, разработчики индей создали компонент TIdAntiFreeze. Достаточно просто кинуть его на форму — и пользовательский интерфейс будет преспокойно перерисовываться во время выполнения блокирующих вызовов.

Вы наверняка уже ознакомились с содержимым различных закладок "Indy (...)" в Delphi. Компонентов там немало, и каждый из них может быть полезным. Я сама работала далеко не со всеми, так как не вижу надобности их изучать без определенной задачи.

В базовый дистрибутив Delphi входят Indy v.9 с копейками. Наверное, желательно сразу сделать обновление до более новой версии (например, у меня сейчас 10.0.76, но есть и более поздние, вроде).

Есть клиентские и серверные компоненты для работы с одними и теми же протоколами. Indy реально упрощают разработку приложений, в отличие от варианта разработки того же самого функционала на сокетах. Например, чтобы установить связь с сервером, вы должны просто-напросто вызвать метод Connect. Успешное установление соединения ознаменуется возвратом из метода без возникновения эксепшена. Если же соединение неызовется установится — вызовется исключение.

"Академический" пример (код не рабочий, не запускайте :) ):

with IndyClient do 
begin
Host := 'test.com';
Port := 2000;
Connect;
Try
// работа с данными (чтение, запись...)
finally
Disconnect;
end;
end;


Host и port могут быть установлены в инспекторе объектов или в рантайме.

Для чего же можно использовать компоненты Indy в задачах парсинга? Применение разнообразно! Самое простое — получение содержимого страницы (с этим уже все, наверное, сталкивались) с использованием компонента IdHTTP:

var
rcvrdata: TMemoryStream;
idHttp1: TidHttp;
begin
idHttp1 := TidHttp.Create(nil);
rcvrdata := TMemoryStream.Create;
idHttp1.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)';
idHttp1.Request.AcceptLanguage := 'ru';
idHttp1.Response.KeepAlive := true;
idHttp1.HandleRedirects := true;
try
idHttp1.Get(Edit1.Text, rcvrdata);
finally
idHttp1.Free;
end;
if rcvrdata.Size > 0 then begin
ShowMessage('Получено ' + inttostr(rcvrdata.Size));
rcvrdata.SaveToFile('c:\111.tmp');
end;
rcvrdata.Free;
end;


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

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

среда, 18 марта 2009 г.

Опыт разработки "универсальных" парсеров

Универсальных парсеров не бывает. На этом можно было бы и закончить статью с таким пафосным названием. :) Но я не закончу, а немного разовью тему на близком мне примере — примере написания парсера форумов.

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

forum parser
(На скрине - англоязычный форум, дабы не светиться :) Хорошо бы к этому делу прикрутить переводчик и синонимайзер :)) )

Вторая — осуществляет постинг. Постинг проходит без обращения к базе, только с использованием данных, в определенной форме сохраненных первой программой. Я уже, вроде, упоминала, что импорт данных в определенном формате пригодится мне потом, когда я буду писать серверный скрипт для постинга (я для себя решила, что изучу, наконец, возможности PHP в этой области. Правда, пока не известно, когда дойдут руки).

Итак, перед созданием программы я села и подумала, как бы мне все так универсально сделать, чтобы прога без проблем смогла отпарсить любой форум. Недолгие размышления привели к пониманию того, что задуманный перфектум не реализовать. Да, такое часто бывает :) Далее в ход идет принцип "разделяй и властвуй". Я проанализировала 3 распространенных форумных движка и один самописный форум. И отделила универсальное от частного. К универсальному отнесла то, что можно единообразно получить со всех форумов с использованием регулярных выражений (названия и ссылки разделов, заголовки и ссылки тем и "технические" переменные, необходимые для парсинга (ссылки для постраничного перелистывания тем и сообщений)). К частному отнесла разбор сообщений. Для каждого движка он получился свой. Таким образом сообщения лучше всего очистить от всякого мусора.

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

При "распарсивании" сообщений пришлось еще учесть формат вывода даты создания сообщений и написать несколько функций для приведения даты в нужный вид. Тип формата даты тоже внесла в базу для каждого форума. Такие дела.
___

В последнее время редко получается писать в блог. Отчасти из-за того, что много работы (свой проект + фриланс). Но заметила, что количество подписчиков увеличивается. Это очень приятно, привет всем ;) Когда задумывала блог, планировала писать посты на темы последовательно, ориентируясь на новичков. После написания ряда таких статей я перешла к рассказам, что можно сделать, обладая базовыми знаниями. А сейчас вот думаю: пусть изложение будет немного непоследовательным, но я время от времени буду возвращаться к некоторым моментам, которые для меня ясны и понятны, а для начинающих могут оказаться полезными. Тем более, что с гугля много переходов именно по запросам, связанным с кодом. В общем, достаточно узкая тематика блога не помешает его периодическому пополнению новыми материалами.

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

понедельник, 9 марта 2009 г.

Отладка программ на Delphi и выявление возникающих ошибок

При разработке программ бывает иногда сложно выловить исключения, ведущие к ошибке: каждый шаг логировать затратно. Сегодня я хочу рассказать об одном компоненте, помогающем мне в отладке программ и локализации возникающих ошибок. Этот компонент называется EurekaLog. Чтобы начать им пользоваться, достаточно скачать его и установить (найти компонент можно в инете). После установки больше ничего не требуется, он будет автоматически включаться во все ваши проекты (в юзезах появится ExceptionLog).

Как использовать ЭврикуЛог?
После компиляции и запуска программы все эксепшэны будут логироваться в файле с тем же названием, что и название программы, но с расширением ".elf" в каталоге проекта. Там вы детально сможете посмотреть все Exception Threads: когда произошел эксэпшн, exception class, exception message и список вызываемых процедур/методов (вплоть до номера строки кода), которые привели в этому.

EurekaLog отладка программ
На рисунке — скриншот открытого elf-файла. В верхней части формы — список исключений. После выбора элемента в верхнем списке, в нижнем списке на вкладке Call Stack можно посмотреть детализацию.


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

понедельник, 2 марта 2009 г.

Пост, оправдывающий надежды посетителей :)

На мой блог с завидной периодичностью заходят посетители по поисковому запросу "ники от А до Я". К сожалению, они не находят тут того, чего хотят (я так думаю... хотя — кто знает). Решила хоть как-то подсластить им горечь разочарования от бесполезного перехода и выложить базу ников, напарсенных мной с одного ресурса.

В архиве 2 файла: girl_users.txt и boy_users.txt (ники из профилей, у которых в графе "Пол" указаны, соответственно, "Женский" и "Мужской"). Женских — 11524, мужских — 11881. Единственно, что там нет деления на ники, состоящие только из латинских символов или не только из латинских символов :) Так что без предварительной обработки эти списки нельзя будет использовать для логинов.

В общем, качайте базу ников. :) Несмотря на то, что это не все ники от а до я, но хоть что-то! :)

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

Поделиться