Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.03.30;
Скачать: CL | DM;

Вниз

получить список ссылок   Найти похожие ветки 

 
Аврам   (2008-03-02 03:21) [0]

Хочу сделать аналог Telepot Pro,web transporter.
первая мысль это скачаивать index, искатьв нем ссылки и по ним проходиться по всем и в найденых искать ссылки и т.д. но цикл получиться бесконечный, как решить это твопрос?
может быть проверять ссылку, есть она в списке или нет..
жду ответов


 
palva ©   (2008-03-02 11:05) [1]

> может быть проверять ссылку, есть она в списке или нет..
А что, здравая мысль.
В Teleport Pro кроме того задается максимальная глубина спуска по ссылкам. По умолчанию 3, по-моему.


 
Аврам   (2008-03-03 12:06) [2]


> В Teleport Pro кроме того задается максимальная глубина
> спуска по ссылкам


это как, получем ссылки с главной страницы, далее заходим на первую,найденные на ней ссылки на первую заходим - это глубина 2 ?


 
Kolan ©   (2008-03-03 14:16) [3]

Ну да это и есть глубина.

а еще можно получать ссылки  только с указанного сайта и наружу не лезть&#133


 
Palladin ©   (2008-03-03 14:20) [4]

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


 
Chorniy   (2008-03-03 14:29) [5]

делай базу данных с 3 полями (адрес, откуда на него сослались, глубина)

1. Находишь ссылки на исходной странице, добавляешь все в базу, перед добавлением смотришь нет ли уже такой в базе данных. всем найденным ставишь глубину "0"

2. По каждой ссылке из БД заходишь... ищешь ссылки, проверяешь не повторяется ли она, добавляешь в базу,  ставишь глубину "1".

3. Делаешь запрос к БД, выбираешь те ссылки у которых глубина = 1, по ним заходишь... и так далее.


 
Аврам   (2008-03-03 18:04) [6]

спасибо за овтеты! только не понятно зачем в базу заносить глубину если мы ее потом не используем для проверки?


 
Аврам   (2008-03-03 18:07) [7]

а понял! это чтобы не заходить по ссылкам у которых глубина меньше текущей


 
Аврам   (2008-03-03 18:24) [8]

а вот поле "откуда на него сослались" точно не понятно зачем! ведь проверять то я буду по первому полю если оно там.


 
Аврам   (2008-03-04 00:09) [9]

делаю так: захожу на главную страницу,забираю оотуда все ссылки, заношу в грид и ставлю рядом в колонке ихнюю глубину(1), затем прохожусь по следующим ссылкам в этом же гриде и забираю оотуда ссылки,опять закидываю их в грид.
кому нетрудно взгляните и скажите как улучшить, а то работает медленно и похоже не совсем верно:



var
 j, p, w, g, a, n, h, l, b: integer;
 s: string;
 i, q: Integer;
 pos_2: string;
 pos_1: Tstringlist;
 list_nalichie: TStringList;
 povtor_ssilki: Boolean;
 url, url_: string;
 list: wideString;
 glubina: Integer;
 xz,gg: boolean;
 col_cd,cx:Integer;
begin

 url := "http://www.firsthealthgallery.com";
 url_ := url;
 list := GetUrl(url);
 list_nalichie := TStringList.Create; // тута содержиться текст который я ищу в ссылке(в нашем случае это php,html)
 list_levak := TStringList.Create;
 list_nalichie.Add(".htm");
 list_nalichie.Add(".php");
 pos_1 := TStringList.Create; //  с чего начинаются ссылки
 pos_1.Add("href="");
 pos_1.Add("action="");
 pos_1.Add("value="");
 glubina := -1;

 if Posex("/", url, 8) > 0 then
   Delete(url, Posex("/", url, 8), lengtH(url));

 gg:=False;

 pos_2 := """;
 povtor_ssilki := True;
 j := 0;

 for b := 0 to 2 do
 begin
   Inc(glubina);

   for l := 0 to StringGrid1.RowCount - 1 do
   begin

     if glubina <> 0 then
     begin
       url := StringGrid1.Cells[0, l];
       list := GetUrl(url);
       if PosR2L("/", url) >= 7 then
         url := Copy(url, 1, PosR2L("/", url) - 1);
     end;
     if list <> "" then
       for h := 0 to pos_1.Count - 1 do
       begin
         j := 0;
         while j <> lengtH(list) do
         begin
           Application.ProcessMessages;
           col_cd := 0;
           inc(j);
           S := "";
           if PosEx(pos_1.Strings[h], list, J) > 0 then
           begin
             for P := PosEx(pos_1.Strings[h], list, J) + length(pos_1.Strings[h]) to
               Length(list) do
               if list[P] <> pos_2 then
                 S := S + list[P]
               else
                 break;
             J := P;
             q := 0;
             col_cd := 1;

             for a := 1 to length(s) do
             begin
               if Copy(s, 1, 3) = "../" then
               begin
                 Delete(s, 1, 3);
                 Inc(col_cd);
               end
               else
                 Break;
             end;

             if glubina <> 0 then
             begin
               url := StringGrid1.Cells[0, l];
               for n:=0 to col_cd - 1 do
                 if PosR2L("/", url) >= 7 then
                   Delete(url, PosR2L("/", url),Length(url));
             end;

             if (Copy(s, 1, 3) <> "www") and (Copy(s, 1, 3) <> "WWW") and (Copy(s, 1, 4) <> "http") and (Copy(s, 1, 4) <> "HTTP") then
               s := url + "/" + s;

             if Copy(s,1,Length(url_)) = url_ then
             if list_nalichie.Count <> 0 then
             begin
               for i := 0 to list_nalichie.Count - 1 do
                 if PosEx(list_nalichie.Strings[i], s, 1) <> 0 then
                 begin

                   label1.Caption := IntToStr(StringGrid1.RowCount);
                   if povtor_ssilki then
                   begin
                     if not ADDString(StringGrid1, s, 0) then
                     begin
                       if StringGrid1.Cells[0, 0] = "" then
                         StringGrid1.RowCount := StringGrid1.RowCount
                       else
                         StringGrid1.RowCount := StringGrid1.RowCount + 1;

                       StringGrid1.Cells[0, StringGrid1.RowCount - 1] := S;
                       StringGrid1.Cells[2, StringGrid1.RowCount - 1] := IntToStr(Glubina);
                     end;
                   end
                   else
                   begin
                     StringGrid1.RowCount := StringGrid1.RowCount + 1;
                     StringGrid1.Cells[0, StringGrid1.RowCount - 1] := S;
                     StringGrid1.Cells[2, StringGrid1.RowCount - 1] := IntToStr(Glubina);
                   end;
                 end;
             end else
               if povtor_ssilki then
               begin
                 if not ADDString(StringGrid1, s, 0) then
                 begin
                   if StringGrid1.Cells[0, 0] = "" then
                     StringGrid1.RowCount := StringGrid1.RowCount
                   else
                     StringGrid1.RowCount := StringGrid1.RowCount + 1;

                   StringGrid1.Cells[0, StringGrid1.RowCount - 1] := S;
                   StringGrid1.Cells[2, StringGrid1.RowCount - 1] := IntToStr(Glubina);

                 end
                 else
                 begin
                   StringGrid1.RowCount := StringGrid1.RowCount + 1;
                   StringGrid1.Cells[0, StringGrid1.RowCount - 1] := S;
                   StringGrid1.Cells[2, StringGrid1.RowCount - 1] := IntToStr(Glubina);
                 end;
               end;
           end;
         end;
       end;
   end;

 end;

 label1.Caption := "end : " + IntToStr(StringGrid1.RowCount);

 list_nalichie.Free;
 list_levak.Free;
 pos_1.Free;


 
Аврам   (2008-03-04 00:10) [10]

функции для работы

function PosR2L(const FindS, SrcS: string): Integer;
 function InvertS(const S: string): string;
 {&#200;&#237;&#226;&#229;&#240;&#241;&#232;&#255; &#241;&#242;&#240;&#238;&#234;&#232; S}
 var i, Len: Integer;
 begin
   Len := Length(S);
   SetLength(Result, Len);
   for i := 1 to Len do
     Result[i] := S[Len - i + 1];
 end;
var ps: Integer;
begin
 ps := Pos(InvertS(FindS), InvertS(SrcS));
 if ps <> 0
   then Result := Length(SrcS) - Length(FindS) - ps + 2
 else Result := 0;
end;

function ADDString(Grid: TStringGrid; Text: string; Col: Integer): Boolean;
var
 i: integer;
begin
 Result := False;
 for i := 0 to Grid.RowCount - 1 do
   if Grid.Cells[Col, i] = Text then
   begin
     Result := True;
     Exit;
   end;
end;

//функция от rouse (c)
const
 HTTP_PORT = 80;
 CLRF = #13#10;
 Header = "Content-Type: application/x-www-form-urlencoded" + CLRF;

function DelHttp(URL: string): string;
begin
 if Pos("http://", URL) > 0 then Delete(Url, 1, 7);
 Result := Copy(Url, 1, Pos("/", Url) - 1);
 if Result = "" then Result := URL;
end;

function GetUrl(const URL: string): string;
var
 FSession, FConnect, FRequest: HINTERNET;
 FHost, FScript: string;
 Ansi: PAnsiChar;
 Buff: array[0..1023] of Char;
 BytesRead: Cardinal;
begin
 Result := "";
 // &#205;&#229;&#225;&#238;&#235;&#252;&#248;&#238;&#233; &#239;&#224;&#240;&#241;&#232;&#237;&#227;
 // &#226;&#251;&#242;&#224;&#241;&#234;&#232;&#226;&#224;&#229;&#236; &#232;&#236;&#255; &#245;&#238;&#241;&#242;&#224; &#232; &#239;&#224;&#240;&#224;&#236;&#229;&#242;&#240;&#251; &#238;&#225;&#240;&#224;&#249;&#229;&#237;&#232;&#255; &#234; &#241;&#234;&#240;&#232;&#239;&#242;&#243;
 FHost := DelHttp(Url);
 FScript := Url;
 Delete(FScript, 1, Pos(FHost, FScript) + Length(FHost));

 // &#200;&#237;&#232;&#246;&#232;&#224;&#235;&#232;&#231;&#232;&#240;&#243;&#229;&# 236; WinInet
 FSession := InternetOpen("DMFR", INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
 if not Assigned(FSession) then Exit;
 try
   // &#207;&#238;&#239;&#251;&#242;&#234;&#224; &#241;&#238;&#229;&#228;&#232;&#237;&#229;&#237;&#232;&#255; &#241; &#241;&#229;&#240;&#226;&#229;&#240;&#238;&#236;
   FConnect := InternetConnect(FSession, PChar(FHost), HTTP_PORT, nil,
     "HTTP/1.0", INTERNET_SERVICE_HTTP, 0, 0);
   if not Assigned(FConnect) then Exit;
   try
     // &#207;&#238;&#228;&#227;&#238;&#242;&#224;&#226;&#235;&#232;&#226;&#224;&#229;&# 236; &#231;&#224;&#239;&#240;&#238;&#241; &#241;&#242;&#240;&#224;&#237;&#232;&#246;&#251;
     Ansi := "text/*";
     FRequest := HttpOpenRequest(FConnect, "GET", PChar(FScript), "HTTP/1.0",
       "", @Ansi, INTERNET_FLAG_RELOAD, 0);
     if not Assigned(FConnect) then Exit;
     try
       // &#196;&#238;&#225;&#224;&#226;&#235;&#255;&#229;&#236; &#231;&#224;&#227;&#238;&#235;&#238;&#226;&#234;&#232;
       if not (HttpAddRequestHeaders(FRequest, Header, Length(Header),
         HTTP_ADDREQ_FLAG_REPLACE or
         HTTP_ADDREQ_FLAG_ADD)) then Exit;
       // &#206;&#242;&#239;&#240;&#224;&#226;&#235;&#255;&#229;&#236; &#231;&#224;&#239;&#240;&#238;&#241;
       if not (HttpSendRequest(FRequest, nil, 0, nil, 0)) then Exit;
       // &#207;&#238;&#235;&#243;&#247;&#224;&#229;&#236; &#238;&#242;&#226;&#229;&#242;
       FillChar(Buff, SizeOf(Buff), 0);
       repeat
         Result := Result + Buff;
         FillChar(Buff, SizeOf(Buff), 0);
         InternetReadFile(FRequest, @Buff, SizeOf(Buff), BytesRead);
       until BytesRead = 0;
     finally
       InternetCloseHandle(FRequest);
     end;
   finally
     InternetCloseHandle(FConnect);
   end;
 finally
   InternetCloseHandle(FSession);
 end;
end;
//################################################################################ ###################################################################


 
Аврам   (2008-03-04 22:59) [11]

уважаемые мастера, прошу подкинуть идею. получается что пока не загрузиться страница в переменную list, то проходит время, а ведь можно наверно куда ее ппараллельно парсингу закачивать и по очереди давать на ссъедение парсеру и так быстрее будет, и не надо будет тратать время на скачкую.
прошу хоть намекнуть как решить этот вопрос!


 
Chorniy   (2008-03-05 08:11) [12]


> как улучшить, а то работает медленно

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


> откуда на него сослались

а это тебе всерно пригодится, например для создания дерева ссылок...


> как решить этот вопрос

создай поток поиск ссылок вынеси в него, загрузку страниц оставь в основном.

Сначала реализуй использование БД, возможно что прирост скорости сделает пункт с потоком ненужным.


 
Chorniy   (2008-03-05 08:17) [13]


> может быть проверять ссылку, есть она в списке или нет..


дак ты сам же задал этот вопрос... и сам же [9] не учитываешь это в алгоритме... цикличность то не исключена.


 
sniknik ©   (2008-03-05 11:42) [14]

> дык я же советовал использовать таблицу базы данных
ну. собственно таблицу базы данных тут лишнее (ему же не нужно хранение, а просто обработка), скорее просто датасет в памяти (ADODataSet например, или клиентский), без визуализации и с индексом по полю, тогда действительно все операции ускорятся на порядки по сравнению с со StringGrid.


 
Аврам   (2008-03-05 15:51) [15]

спасибо за ответы! данных не так много чтобы использовать бд, грида вполне достаточно в моем случае. основная загвостка в том что бывает долго скачиваются страницы т.к. имееют большой объем или сервак медленный.


 
Аврам   (2008-03-05 16:09) [16]


> создай поток поиск ссылок вынеси в него, загрузку страниц
> оставь в основном.

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


 
sniknik ©   (2008-03-05 17:16) [17]

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

> поток это хорошо
только если он к месту...
зачем тебе поток если при варианте с рекордсетом поиск ссылки в сохраненных будет меньше времени занимать чем просто передача этой ссылки в поток, не говоря уже о дальнейшем поиске в нем. и возвращением результата назад... и переделки проги на асинхронную работу.
?

хотя, чисто ради ознакомления с потоками, можеш посмотреть пример в дельфи x:\Program Files\Borland\Delphi7\Demos\Threads
(и не говори, что у тебя другая версия дельфей и т.д.)


 
Аврам   (2008-03-05 17:31) [18]

7-я)))
ссылки выдераются быстро, мне кажется что надо оставить все как есть, все упирается в долгую скачку страницы.



Страницы: 1 вся ветка

Текущий архив: 2008.03.30;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.068 c
15-1202909284
Ega23
2008-02-13 16:28
2008.03.30
Zip-Unzip для Delphi - посоветуйте


2-1204475915
Alex
2008-03-02 19:38
2008.03.30
Как оговорить свойство Lines для работы Memo?


2-1204639747
snake-as
2008-03-04 17:09
2008.03.30
Несколько клавиш


6-1183322193
MOO
2007-07-02 00:36
2008.03.30
Как отследить подключение к Интернет по DialUP?


15-1203107243
NeLd
2008-02-15 23:27
2008.03.30
[win2003 serv] Как программы установленные от администратора