Первое, что я решила опробовать, это библиотека Synapse. Я уже не раз встречала упоминания о ней, но все как-то не доводилось поработать.
Скачиваем, устанавливаем.
Установка Synapse
(в моем случае на старенький Delphi 7).1. Распаковать архив в какую-нибудь папку (в Source, например)
2. В меню идем Tools - Environment Options - Library и добавляем в Library Path путь к папке ..Source\SYNAPSE\LIB
3. В новосозданном проекте добавляем в Uses-ы httpsend и synacode (при надобности).
Пришло время "HelloWorld"-а.
Простые примеры кода с использованием Synapse
Давайте начнем с самых простых вещей - с получения содержимого страницы.
Поместим на форму кнопку и TMemo, добавим в uses httpsend, напишем обработчик нажатия кнопки:
procedure TMainF.Button1Click(Sender: TObject);
begin
if not HttpGetText('http://parsing-and-i.blogspot.com', Memo1.Lines) then
ShowMessage('Что-то не получилось.');
end;
После нажатия на кнопку в мемо появилось содержимое страниц. Старт взят: с помощью HttpGetText задачу выполнили.
Дальнейшее изучение библиотеки можно проводить так — заглянуть непосредственно в файл библиотеки (httpsend.pas). Главным классом является THTTPSend. Даже просто изучив его структуру, можно понять принципы работы и возможности.
Итак, HTTPSend.Document возвращает содержимое всего документа. Поэкспериментируем с использованием еще каких-нибудь элементарных функций. Например, получим заголовок страницы и отдельно код ответа.
procedure TMainF.Button2Click(Sender: TObject);
var
HTTP: THTTPSend;
Res : boolean;
begin
HTTP := THTTPSend.Create;
try
Res := HTTP.HTTPMethod('GET', Edit1.Text);
if Res then
begin
Memo1.Lines.AddStrings(HTTP.Headers);
Edit2.Text := IntToStr(HTTP.ResultCode);
end
finally
HTTP.Free;
end;
end;
Задание было несложным. А сейчас попробуем в строке для ввода url набрать "http://yandex.ru". Как известно, если адрес яндекса набирать без "www", то перманентно будет произведен редирект на адрес с "www".
В indy есть удобное свойство. Там если
idHTTP.HandleRedirects := true;
то все редиректы будут обрабатываться автоматически (кто работает с php - в cURL такой параметр тоже есть). А здесь мы наблюдаем:
И никакого HandleRedirects.
Пробуем самостоятельно обработать ситуацию, когда код ответа совпадет с кодом редиректа. Знаем, что в заголовке есть параметр Location, в котором будет указано новое местоположение страницы. Определим новый location, распарсив заголовок.
procedure TMainF.Button2Click(Sender: TObject);
var
HTTP : THTTPSend;
Res : boolean;
n : integer;
NewUrl : string;
begin
HTTP := THTTPSend.Create;
// HTTP.UserAgent:= GetRandomUseragent;
try
Res := HTTP.HTTPMethod('GET', Edit1.Text);
if Res then
begin
Memo1.Lines.AddStrings(HTTP.Headers);
Edit2.Text := IntToStr(HTTP.ResultCode);
// если код ответа 3XX (т.е. есть редирект)
case HTTP.Resultcode of
301, 302, 307:
begin
n := FoundLocationStrNum(HTTP.Headers);
if (n >= 0) and (n <= HTTP.Headers.count) then // если в хэдере найдена строка с локейшеном
begin
NewUrl := StringReplace(HTTP.Headers.Strings[n],'Location: ','',[]);
Edit3.Text := NewURL;
end
else
ShowMessage('В заголовке не найдена ссылка для редиректа');
end;
end;
end
finally
HTTP.Free;
end;
end;
где
function FoundLocationStrNum(Headers: TStringlist): integer;
var
FoundStrPos, i : integer;
begin
Result:= -1;
// ищем в заголовке строку, начинающуюся с "Location: "
for i := 0 to Headers.Count do
begin
FoundStrPos := Pos('Location: ', Headers.Strings[i]);
if FoundStrPos > 0 then
begin
Result:= i; // номер строки, в которой указан Location
exit;
end;
end;
end;
По идее, в том месте, где я для примера вывела в edit3 новый URL, надо снова запрашивать страницу, проверять хэдер и так далее (и все это желательно с учетом максимального количества редиректов). Для этого понадобится написание рекурсивной функции или применение готовых "оберток". Наверняка в сети есть готовые библиотеки для облегчения использования Synapse. Попытаюсь к следующему разу собрать какой-нибудь материал и привести пример работы, сейчас уже не хочется с этим возиться. Главное, что сегодня произошло знакомство с библиотекой и базовыми принципами работы с ней.
Если вы знаете какие-нибудь удобные библиотеки для работы с Synapse — буду рада ссылкам на них в комментариях.
____
Чтобы быть в курсе обновлений блога, можно подписаться на RSS.
Штука, конечно, не плохая, но Вас не смутило, что дата последнего ченджлога 2007 год?
ОтветитьУдалитьпроект больше мертв чем жив.
а инди развивается и развивается...
стремно использовать в своих проектах либы у которых нет будущего.
брать их как базис и дописывать? хм... как вариант, но стоит ли оно того?
to Homolibere
ОтветитьУдалитьА Вы уверены, что смотрели Synapse на правильном сайте
http://www.synapse.ararat.cz
последний стабильный релиз 2009-10-09 - release no. 39
Я - Ваш поклонник отныне и вовеки веков!!! Спасибо за этот блог!
ОтветитьУдалитьУверен, я смотрел сюда http://synapse.ararat.cz/doc/Synapse_history.htm
ОтветитьУдалитьНо и ошибся я тоже. В свн коммиты по новее. Надо будет попробовать.
Вот моя обертка
ОтветитьУдалитьhttp://narod.ru/disk/17696081000/IngHTTPSend.7z.html
Сергей, большое спасибо! Погляжу :)
ОтветитьУдалитьЕсли будут вопросы, пишите на pikhovkins[соб-ка]yandex[тчк]ru
ОтветитьУдалитьЗдравствуйте, у меня на get возвращается код 200, т.е. всё ок, но в Headers нету Location, но нужен редирект по ссылке, там на этой странице есть кнопка по нажанию которой происходит скачивание файла, так вот у меня возник вопрос, это я что то делаю не так или это косяк сайта? получается нужна переадресация, но в получаемом ответе её нет, хотя в теле возвращаемой страницы ссылка на файл есть
ОтветитьУдалитьполучается мне нужно вручную парсить возвращаемый результат что бы получить ссылку на файл?
ps извините если не понятно объяснил, я ещё новичок :)
Да, нужно парсить вручную.
ОтветитьУдалитьДоброго времени суток! У меня вопрос по "синапсу" и парсерам... страничку мы открываем, а как в свое приложение загрузить ее определенную часть, т.е. определенные данные?
ОтветитьУдалитьРаспарсить данные. Разобрать DOM или с помощью регулярных выражений. Большая часть материалов на блоге именно об этом.
ОтветитьУдалитьВесь день провел за поиском и чтением информации о DOM'е и регулярных вырожениях и всетаки не понятно! Как можно достать например цифру в динамичесски создаваемой странице. А если еще и в тексте поподаются ява теги... На ум приходит только Pos('(('***********', Memo1.Text); Пожалуйста обьясните чайнику как это можно сделать!
ОтветитьУдалитьИспользуй регулярные выражения.
ОтветитьУдалитьДоброго времени суток Мария! Нашел в вашем блоге много интересного для себя, до этого и понятия не имел что такое парсер и как его использовать )) Спасибо! При освоении этой области программирования сталкнулся с проблемой, а именно: Используя Synapse загружаю исходный текст веб странички, все нормально до тех пор пока в URL нету кириллицы. При использовании URL.Encode функции (Для проверки запускаю через шелл страничка открывается!!) ничего не получается как быть???
ОтветитьУдалитьАнонимный, я не сталкивалась с кириллицей в URL-ах, не приходилось, так что сходу ответить на вопрос не могу, а пробовать сейчас некогда. Но, может, кто-нибудь из читающих эту статью уже сталкивался и поможет. :)
ОтветитьУдалить>При использовании URL.Encode функции (Для проверки запускаю через шелл страничка открывается!!) ничего не получается как быть???
ОтветитьУдалитьТочнее вот так:
EncodeURL(AnsiToUtf8(Stroka с кириллицей))
Маша а что нужно добавить в Uses чтобы не выдавала ошибку для "GetRandomUserAgent" и т.д. ?
ОтветитьУдалитьУ меня там стоит только HTTPSEND!
Имя, ну и имя у вас :)
ОтветитьУдалитьЗакомментируйте эту строку вообще, она не обязательная. Это у меня функция для подстановки рандомного UserAgent-а. Можно и статически какое-нибудь значение задать.
Что-то я упустила, в листинге в посте сейчас закомментирую, спасибо, что обратили внимание.)
И еще хотел бы дать маленький совет для начинающих парсеров таких как я. Прежде чем анализировать страницу лучше для начала воспользуйтесь утилой HTTP Analyzers 5x. чтоб можно было по быстрому копировать значение GET/POST запросов. Это не только удобно но и с экономит вам много времени. Думаю автор уже в курсе подобных утилит, и мне это кажется лучшим способом.
ОтветитьУдалитьпысы - если не найдете ключ или программу обращайтесь вышлю полную версию.
Подскажите, пожалуйста, как можно средствами Synapse, организовать отправку файла на сервер. Раньше использовал инди (TIdMultipartFormDataStream+Post), решил отказаться, перейти на синапс. Все просто освоилось, только это. Подскажите, пожалуйста, как это использовать в синапсе.
ОтветитьУдалитьShaddy, я еще не настолько хорошо знаю эту библиотеку. Боюсь, что помочь не могу. Может, кто-нибудь из читателей ответит. На всякий случай продублирую вопрос на http://help.sander.su/.
ОтветитьУдалитьПро Synopse много написано на webdelphi.ru, и есть довольно много хороших практических примеров!
ОтветитьУдалитьМаша, доброго дня.
ОтветитьУдалитьУ меня возникла следующая проблема (покажу на примерах):
1.HTTPMethod('GET','213.180.193.3')
2.HTTPMethod('GET','http://www.yandex.ru')
1-ый способ обращения к Яндесу (по IP) работает на ура.
2-ой способ возвращает ошибку 500, и HTML, соответственно, не скачивается.
ps. Использую из-под Анроида, но отлаживаюсь в Lazarus в Win.
Помогите пожалуйста.
Спасибо за статью! Помогла разобраться с ответом от сервера - 301!
ОтветитьУдалить