Форум: "Начинающим";
Текущий архив: 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]Ну да это и есть глубина.
а еще можно получать ссылки только с указанного сайта и наружу не лезть…
← →
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;
{Èíâåðñèÿ ñòðîêè 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 := "";
// Íåáîëüøîé ïàðñèíã
// âûòàñêèâàåì èìÿ õîñòà è ïàðàìåòðû îáðàùåíèÿ ê ñêðèïòó
FHost := DelHttp(Url);
FScript := Url;
Delete(FScript, 1, Pos(FHost, FScript) + Length(FHost));
// Èíèöèàëèçèðóå&# 236; WinInet
FSession := InternetOpen("DMFR", INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if not Assigned(FSession) then Exit;
try
// Ïîïûòêà ñîåäèíåíèÿ ñ ñåðâåðîì
FConnect := InternetConnect(FSession, PChar(FHost), HTTP_PORT, nil,
"HTTP/1.0", INTERNET_SERVICE_HTTP, 0, 0);
if not Assigned(FConnect) then Exit;
try
// Ïîäãîòàâëèâàå&# 236; çàïðîñ ñòðàíèöû
Ansi := "text/*";
FRequest := HttpOpenRequest(FConnect, "GET", PChar(FScript), "HTTP/1.0",
"", @Ansi, INTERNET_FLAG_RELOAD, 0);
if not Assigned(FConnect) then Exit;
try
// Äîáàâëÿåì çàãîëîâêè
if not (HttpAddRequestHeaders(FRequest, Header, Length(Header),
HTTP_ADDREQ_FLAG_REPLACE or
HTTP_ADDREQ_FLAG_ADD)) then Exit;
// Îòïðàâëÿåì çàïðîñ
if not (HttpSendRequest(FRequest, nil, 0, nil, 0)) then Exit;
// Ïîëó÷àåì îòâåò
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