Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.03.30;
Скачать: [xml.tar.bz2];

Вниз

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

 
Аврам   (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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.04 c
15-1203198582
Германн
2008-02-17 00:49
2008.03.30
Ну это надо же так пить!


15-1203020423
KilkennyCat
2008-02-14 23:20
2008.03.30
Требуется специалист в самую лучшую компанию в мире.


4-1184506481
Deeman
2007-07-15 17:34
2008.03.30
Панель задач


2-1204542004
av-mari
2008-03-03 14:00
2008.03.30
Длинное имя?


2-1204363054
makz
2008-03-01 12:17
2008.03.30
Запрос





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский