Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.03.2010, 17:15   #1
ZolanPro
 
Регистрация: 13.09.2009
Сообщений: 9
Счастье Рекурсивный сбор внутренних ссылок с сайта

необходимо собрать все ссылки что есть на сайте (которые ведут к веб странциам - исключаем картинки и файлы). решил использовать рекурсию и регулярные выражения. с одной страницы ещё как-то поулчаеться собрать, а когда включаю рекурсивный сбор прога виснет. вот мой исходник. понимаю что всё достаточно криво риму любые предложения по улучшению и оптимизации кода
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
  IdHTTP, StdCtrls, RegExpr,XPMan;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Memo1: TMemo;
    Button1: TButton;
    IdHTTP1: TIdHTTP;
    Label1: TLabel;
    procedure Linker(URL:String);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
var
  Checked,Remain:TStringlist;

procedure TForm1.Linker(URL:String);
var
  Cache,link: string;
  n,i:integer;
  reg: TRegExpr;
begin
  Cache:=IdHttp1.Get(URL);
  Checked.Add(url);
  Memo1.Lines.Add(url);
  reg:=TRegExpr.Create;
  memo1.Clear;
  n:=0;
  try
    reg.Expression:='<a[^>]+href=([^ >]+)';
    if reg.Exec(Cache) then begin
      repeat
        link:=reg.Match[0];
        //Äîðàáàòûâàåì ññûëêó
        if (ord(link[length(link)])=39) or (link[length(link)]='"')
        or (link[length(link)]=' ') or (link[length(link)]='>') then
          delete(link,length(link),1);
        delete(link,1,pos('href=',link)+4);
        if (ord(link[1])=39) or (link[1]='"')
        or (link[1]=' ') or (link[1]='>') then
          delete(link,1,1);
        //Äîáàâëÿåì íà÷àëî ñàéòà
        if (pos('http://',link)=0) and ((link[1]='\') or (link[1]='/')) then link:=Edit1.Text+link;
        if (pos('http://',link)=0) and (link[1]<>'\') and (link[1]<>'/') and (Edit1.Text[length(edit1.text)]<>'/') then link:=Edit1.Text+'/'+link;
        //Ïîñëåäíÿÿ ïðîâåðêà è äîáàâëÿåì â ìåìî
        if (pos('mailto:',link)=0) and (pos(edit1.text,link)<>0) then
          if (pos(link,checked.Text)=0) and (pos(link,remain.Text)=0) then
            Remain.Add(link);
        n:=n+1;
      until not reg.ExecNext;
    end else
      Memo1.Lines.Add('Ññûëêè íå íàéäåíû!');
  finally
    reg.Free;
  end;
  Label1.Caption:=IntToStr(n);
  Cache:='';
if remain.Count<>0 then
  for i:=0 to remain.Count-1 do
   Memo1.Lines.Add(remain[i]);
    //linker(remain[i]);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
linker(edit1.text);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Checked:=TStringList.create;
Remain:=TStringList.create;
end;

end.
ZolanPro вне форума Ответить с цитированием
Старый 06.03.2010, 18:14   #2
mihali4
*
Старожил
 
Регистрация: 22.11.2006
Сообщений: 9,201
По умолчанию

А где у вас то, что вы называете рекурсией ?
Я вижу только закомментированную строку, которая просто организует бесконечный цикл...
Вы проанализируйте свой код - begin..end еще никто не отменял.
mihali4 вне форума Ответить с цитированием
Старый 06.03.2010, 18:25   #3
ZolanPro
 
Регистрация: 13.09.2009
Сообщений: 9
По умолчанию

//linker(remain[i]);
мм по сути это и есть рекурсия сорь просто кидал исходник где тестил сам сбор ссылок.
ZolanPro вне форума Ответить с цитированием
Старый 06.03.2010, 19:28   #4
mihali4
*
Старожил
 
Регистрация: 22.11.2006
Сообщений: 9,201
По умолчанию

Я так и не понял - дошло или нет ?
Код:
if remain.Count<>0 then
  for i:=0 to remain.Count-1 do
begin
   Memo1.Lines.Add(remain[i]);
   linker(remain[i]);
end;
mihali4 вне форума Ответить с цитированием
Старый 06.03.2010, 22:20   #5
ZolanPro
 
Регистрация: 13.09.2009
Сообщений: 9
По умолчанию

Да не в этом дело! Бегин и энд убраны потому что тестил с добавлением найденных ссылок либо в Мемо либо их обработка этойже функцией - рекурсия. Оба варианта не предусмотрены! Поэтмуо и нет операторных скобок.
ZolanPro вне форума Ответить с цитированием
Старый 07.03.2010, 12:33   #6
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

обычно страницы сайта имеют такую функцию как НА ГЛАВНУЮ (вернуться) (при чистой рекурсии мы и получим бесконечный цикл

Главная страница -> какая-то страница ->вернуться снова главная

вы как-то учитываете это (да и вообще перекрестные ссылки на страницвх) в своей программе.
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 07.03.2010, 13:48   #7
ZolanPro
 
Регистрация: 13.09.2009
Сообщений: 9
По умолчанию

да учитывал я это
if (pos(link,checked.Text)=0) and (pos(link,remain.Text)=0) then
Если уже проверена ссылка но не лезем
ZolanPro вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
рекурсивный алгоритм. Nelson1992 Помощь студентам 9 21.03.2010 12:09
Рекурсивный алгоритм SVM Общие вопросы C/C++ 7 13.11.2009 09:24
Разработать рекурсивный алгоритм lucky Паскаль, Turbo Pascal, PascalABC.NET 4 08.05.2009 15:04
парсер (сбор ссылок с сайта) AlexMenco Фриланс 9 24.02.2009 19:39
Сбор инфы с сайта. Mss_Smith Помощь студентам 6 17.06.2007 16:26