Форум   Статьи   Новости   Файлы   Bugtraq   Сниффер   Друзья   О Клубе

Последнее на Форуме

Пожертвования

Liberty Reserve: U9999024
Кошельки WebMoney:
Z583322939655
E121331800314
R274644017049
U349709454906


YM: 410011220120073

Пожертвовать

Контакты

Связь с Администрацией

hpcteam1[@]gmail.com

Статьи rss

[ Добавить Статью на сайт ]

Статьи / Программирование / Delphi

Создание многопоточного парсера для файлообменной сети Slil.Ru

Доброго времени суток. С вами я, PsiBoX.

Предлагаю вам познакомиться со статьей "Создание многопоточного парсера файлов для файлообменной сети Slil.ru"

Что нам понадобиться для работы?
Пожалуй, только сама система Delphi (Лично я использую Delphi 7 Enterprise).

Итак, приступим.

Slil.ru - файлообменная система. Часто люди относятся к ней как к мусорке, отправляя туда важные сведения незащищенными. Там можно найти и почтовые базы (однажды, я выловил такую на 100тыс. аккаунтов), и пароли, и много всякой всячины.
При загрузке файла сервер генерирует для него такую ссылку: http://slil.ry/xxxxxxxx
Все 8 "х" представляют собой цифры.

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

Для начала, нам надо будет поместить на форму 5 полей ввода(Edit), 1 поле текста(Memo), а так же пару кнопок(Button), одну SpeedButton и SaveDialog с палитры Dialogs.
Сгруппировать вы можете их на свое усмотрение, вот что получилось у меня:

IMG: http://s010.radikal.ru/i314/1101/23/049fb1dd462c.jpg

Теперь, в кратце, принцип работы нашей программы:
1)Вводим начальный и конечный индекс, число потоков, задаем расширение;
2)Запускаем программу, наблюдаем за пополнением списка файлов;
3)Сохраняем список в файл, заданный пользователем.

Переходим к самому процессу кодинга.
Для начала, нам надо добавить в uses XpMan(Для красоты), UrlMon, SyncObj.

После этого мы должны описать свой класс-потомок от класса TThread (класс TThread вляется абстрактным и его нельзя использовать напрямую). Описание вставляем после класса вашей формы.

type
  TMyThread = class(TThread)
    CurrentIndex: integer; 
	FileName:String;
    procedure Execute; override;
    procedure Sunc;
  end;

Теперь, в глобальных переменных в разделе var мы должны описать следующие переменные:

a: Array [1..400] of TMyThread; //массив наших потоков
CS: TCriticalSection; //Критическая секция для синхронизации потоков
Current,Max,ThreadCount, Ended: integer; //Переменные для хранения индексов и числа потоков

Объявим две процедуры:

procedure TForm1.FormCreate(Sender: TObject);
begin
Cs:=TCriticalSection.Create; //Создание критической секции
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
CS.Free; //Уничтожение критической секции.
end;

Теперь опишем получение файла для сохранения отчета.
(Т.к. у нас всего один SpeedButton на форме, я не стал давать ему другое имя, оставил SpeedButton1)

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
if SaveDialog1.Execute then //Если Выполнен SaveDialog, то
FileEdit.Text:=SaveDialog1.FileName; //Грузим в edit путь к файлу
end;

Теперь я объясню некоторые подробности процесса парсинига.
Админы Slil.ru работу свою знают и всячески предотвращают парс страниц. Я не смог получить содержимое страницы ни с помощью Indy, ни с помощью WinSock. Я всячески игрался с передаваемыми заголовками, но в ответ по-прежнему была пустая страница. Если кто найдет способ получить страницу через Инди, просьба сообщить об этом автору =).
Ну а мы с вами пока будем использовать стандартный системный объект Urlmon (вспомните, мы подключили его в uses).

Для получения имени файла со страницы, я написал небольшую функцию. В качестве параметра ей надо передать индекс страницы, а она вернет либо имя файла, либо "Can't find the page', что означает, что такой страницы не существует.
Вот она сама:

function GetFileOnURL(a: String): string;
var s:TStringList; ss:String; i:integer;
begin
ss:=''; //Обнуляем строку
urlmon.URLDownloadToFile(nil,PChar('http://slil.ru/'+a),PChar(a),0,nil); //Получаем содержимое страницы в файл, имя которого - индекс страницы
s:=TStringList.Create; //Создаем StringList
if FileExists(a) then begin //Проверяем, существует ли файл?
s.LoadFromFile(a); //Если да, то грузим его содержимое
DeleteFile(a); //И удаляем его
For i:=Pos('<p align="center">',s.Text)+20 to pos('&nbsp;&nbsp;&nbsp;',s.Text)-1 do //Парсим страницу
ss:=ss+s.Text[i]; //И сохраняем в переменную ss имя файла
Result:=ss; //Присваеваем результату имя файла
end else //Если файла нет, то
Result:='Can''t find the page'; //Присваеваем результату сообщение об ошибке.
end

Основа для парсинга подготовлена, теперь надо организовать это все в потоках. Здесь все так же очень просто.
Мы будем использовать две процедуры: одна - главный процесс потока, а другая - вспомогательная, для вывода файла в Мемо.
Переместите курсор на TMyThread и нажмите Ctrl+Shift+C. После заполните процедуру так:

procedure TMyThread.Execute;
begin
while (not terminated) and (CurrentIndex<=Max) do begin //Пока не завершили
CS.Enter; //Входим в критическую секцию (Синхронизация)
CurrentIndex:=Current; //Сохраняем индекс в переменную внутри потока
Form1.CurrentLabel.Caption:=IntToStr(Current); //Выводим индекс в Лейбл на форме
Current:=Current+1; //Увеличиваем индекс
CS.Leave; //Покидаем критическую секцию
FileName:=GetFileOnURL(IntToStr(CurrentIndex)); //Получаем имя файла по ссылке
Synchronize(Sunc); // Запускаем вторую процедуру
end; //Конец цикла
CS.Enter; //Входим в критическую секцию
Ended:=Ended+1; //Увеличиваем показатель завершения
if Ended>=ThrCount then begin //Если показатель нужный, то
Form1.StopButton.Enabled:=false; //
Form1.StartButton.Tag:=0; // устанавливаем исходные значения для кнопок.
Form1.StartButton.Caption:='Старт'; //
Form1.Memo1.Lines.SaveToFile(Form1.FileEdit.Text); //Сохраняем результат в файл
Form1.ClearButton.Enabled:=true; //и делаем доступной кнопку очистки.
end;
CS.Leave; //Выход из критической секции.
end;

procedure TMyThread.Sunc;
begin
if length(Form1.ExtEdit.Text)<=1 then //Проверяем, выводить все файлы или только по фильтру
Form1.Memo1.Lines.Add('http://slil.ru/'+IntToStr(CurrentIndex)+'   -   '+FileName)//
else begin//
if copy(FileName,length(FileName)-length(Form1.ExtEdit.Text)+1,length(Form1.ExtEdit.Text))=Form1.ExtEdit.Text then//
Form1.Memo1.Lines.Add('http://slil.ru/'+IntToStr(CurrentIndex)+'   -   '+FileName);//
end;
end;

При получении нескольких первых файлов (по числу потоков), порядок их следования будет неправильным из-зи специфики работы UrlMon. Остальные файлы будут идти по порядку.

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

procedure TForm1.StartButtonClick(Sender: TObject);
Var i:integer;
begin
if StartButton.Tag=0 then begin
Current:=StrToInt(MinEdit.Text);
Max:=StrToInt(MaxEdit.Text);
ThrCount:=StrToInt(ThreadEdit.Text);
StartButton.Caption:='Пауза';
StartButton.Tag:=10;
For i:=1 to ThrCount do
a[i]:=TMyThread.Create(false);
StopButton.Enabled:=true;
ClearButton.Enabled:=false;
exit;
end;
if StartButton.Tag=10 then begin
StartButton.Tag:=20;
StartButton.Caption:='Продолжить';
for i:=1 to ThrCount do
a[i].Suspend;
Exit;
end;
if StartButton.Tag=20 then begin
StartButton.Tag:=10;
StartButton.Caption:='Пауза';
for i:=1 to ThrCount do
a[i].Resume;
Exit;
end;
end;

procedure TForm1.ClearButtonClick(Sender: TObject);
begin
Memo1.Clear;
end;

procedure TForm1.StopButtonClick(Sender: TObject);
var i:integer;
begin
For i:=1 to thrCount do
a[i].Terminate;
StartButton.Tag:=0;
StartButton.Caption:='Старт';
StopButton.Enabled:=false;
end;

Вот и все! Теперь можешь пустить свой парсер в дело. На практике оказалось, что это очень даже полезная вещь.
Удачи тебе в твоих начинаниях.

К статье прилагается архив с исходным кодом и откомпилированным файлом.
http://www.sendspace.com/file/zpca88

Автор: PsiBoX

Источник: Hacker-pro.net

Материал добавил PsiBoX


Комментарии(1)

Дата: 2011-01-10 19:11:10

Добавить Комментарий к Материалу

Вы должны быть авторизованы на форуме чтобы добавлять комментарии. Регистрация Уже авторизованы?

Комментарии к Материалу

 Beslan              2011-06-08 21:12:19

spasibo,

Последнее на Сайте

Новости

Статьи

Bugtraq

Файлы

Copyright © 2008 - 2017 «HPC». При копировании материалов ставьте ссылку на источник.
Все материалы представлены только в ознакомительных целях, администрация за их использование ответственности не несет.
Пользовательское соглашение Реклама на сайте