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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 16.04.2013, 19:57   #1
chex01
Пользователь
 
Аватар для chex01
 
Регистрация: 06.03.2011
Сообщений: 31
Вопрос Проблема с потоками (парсинг всех ссылок сайта)

Доброго времени суток дорогие форумчане!
Делаю программу для сбора всех ссылок с сайта. Есть список ссылок для обработки и N-ое количество потоков, а так же критическая секция(КС). При выходе из КС у потока есть номер строки(CurLnk) которую нужно обрабатывать.

Изначально в списке одна ссылка, соответственно её обрабатывает поток получивший CurLnk:=0, т.е. самый первый поток. Пока поток не обработал эту самую ссылку список пуст (*После обработки в список добавляются новые ссылки полученные с обработанной ранее ссылки) и для остальных потоков попросту нет данных для обработки, но свой номер строки они получают, а это чревато пропуском количеству ссылок равному количеству потоков с пустым значением.

Как можно В ПОТОКЕ подождать входных данных, т.е. чтобы например у второго потока (с CurLnk:=1) пустая строка получила ссылку после того как появятся ссылки необработанные в первом потоке.

Код:
procedure TForm1.Button2Click(Sender: TObject);
begin
  Lnk := -1;
  Work:=true;

  Form1.Memo_List.Lines.Add(Form1.url_link.Text); // для самой первой ссылки

for Thread := 1  to StrToInt(Edit1.Text) do
  TNewThread.Create(false);

  Thread := StrToInt(Edit1.Text);
end;
Код:
procedure TNewThread.Execute;
var
  CurLnk: integer;
  HTTP: TIdHTTP;
begin
 while Work do
  begin
   CS.Enter;
     Inc(Lnk);
     if Form1.Memo_List.Lines.Count <> Form1.Memo_Ok.Lines.Count + Form1.Memo_Error.Lines.Count
     then CurLnk := Lnk else Work := false;
   CS.Leave;

   if Work then
    begin
    //// как же подождать входных данных??? ////////
     while Form1.Memo_List.Lines[CurLnk] = '' do Sleep(5000);
    /////////////////////////////////////////////////////////

     URL := Form1.Memo_List.Lines[CurLnk];

     HTTP := TIdHTTP.create(nil);
     HTTP.HandleRedirects := true;

       try
        Page := HTTP.Get(URL);
        Rez := 1;
       except
        if pos(URL,Form1.Memo_Error.Text) = 0 then
        Rez := 0;
       end;

     HTTP.Free;
     Synchronize(Sync);
    end;
  end;

 dec(Thread);
 if Thread = 0 then ShowMessage('Все ссылки найдены!');
end;
Код:
procedure TNewThread.Sync;
var
  link : string;
  reg: TRegExpr;
begin
 case Rez of
   0:begin  // Ошибка HTTP
          Form1.Memo_Error.Lines.Add(URL);
     end;
   1:begin  // добавляем в список проверенных после проверки на повторение
          if pos(URL,Form1.Memo_OK.Text) = 0 then
          Form1.Memo_OK.Lines.Add(URL);

          reg := TRegExpr.Create;
          try
            reg.Expression:='<a[^>]+href=([^ >]+)';
            if reg.Exec(Page) 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:=Form1.url_link.Text + link;
                if (pos('http://',link)=0) and (link[1]<>'\') and (link[1]<>'/') and (Form1.url_link.Text[length(Form1.url_link.text)]<>'/') then link:=Form1.url_link.Text+'/'+link;
                if (pos('mailto:',link)=0) and (pos(Form1.url_link.text,link)<>0) then
                // Если не проверена добавляем в очередь
                if (pos(link,Form1.Memo_Ok.Lines.Text)=0) and (pos(link,Form1.Memo_List.Text)=0) then
                   Form1.Memo_List.Lines.Add(link);
              until not reg.ExecNext;
                end;
                finally
                  reg.Free;
                  Page := '';
                end;
              end;
          end;
end;
chex01 вне форума Ответить с цитированием
Старый 16.04.2013, 21:00   #2
eval
Подтвердите свой е-майл
 
Регистрация: 29.08.2012
Сообщений: 4,011
По умолчанию

это пять !
eval вне форума Ответить с цитированием
Старый 16.04.2013, 21:37   #3
chex01
Пользователь
 
Аватар для chex01
 
Регистрация: 06.03.2011
Сообщений: 31
Вопрос

Цитата:
Сообщение от eval Посмотреть сообщение
это пять!
Предложите другой вариант реализации парсинга в потоке?

Строка ниже только для того что-бы не забивать список ошибок пустыми строками:
Код:
//// как же подождать входных данных??? ////////
     while Form1.Memo_List.Lines[CurLnk] = '' do Sleep(5000);
/////////////////////////////////////////////////////////
chex01 вне форума Ответить с цитированием
Старый 16.04.2013, 21:42   #4
eval
Подтвердите свой е-майл
 
Регистрация: 29.08.2012
Сообщений: 4,011
По умолчанию

при чем тут парсинг, тут до парсинга еще далеко, тут надо начинать с вопроса а зачем и для чего нужны потоки?
eval вне форума Ответить с цитированием
Старый 16.04.2013, 21:46   #5
chex01
Пользователь
 
Аватар для chex01
 
Регистрация: 06.03.2011
Сообщений: 31
Смущение

Цитата:
Сообщение от eval Посмотреть сообщение
надо начинать с вопроса а зачем и для чего нужны потоки?
Будьте так любезны объяснить в чём моя ошибка.
chex01 вне форума Ответить с цитированием
Старый 16.04.2013, 22:01   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,430
По умолчанию

Цитата:
Предложите другой вариант реализации парсинга в потоке?
Угу, регулярные выражения и без гемороя.
Цитата:
при чем тут парсинг, тут до парсинга еще далеко, тут надо начинать с вопроса а зачем и для чего нужны потоки?
Список сайтов опрашивается.
Человек_Борща вне форума Ответить с цитированием
Старый 16.04.2013, 22:07   #7
eval
Подтвердите свой е-майл
 
Регистрация: 29.08.2012
Сообщений: 4,011
По умолчанию

Цитата:
Угу, регулярные выражения и без гемороя.
там они и применяются, токо странно, мягко говоря, как и все остальное

вопрос не в том что автор хочет сделать, а в том что он не понимает что делает

Последний раз редактировалось eval; 16.04.2013 в 22:09.
eval вне форума Ответить с цитированием
Старый 16.04.2013, 22:35   #8
chex01
Пользователь
 
Аватар для chex01
 
Регистрация: 06.03.2011
Сообщений: 31
Стрелка

Цитата:
Сообщение от Человек_Борща Посмотреть сообщение
регулярные выражения и без гемоРроя
Цитата:
Сообщение от eval Посмотреть сообщение
там они и применяются
Как уже заметил многоуважаемый eval, который не поленился посмотреть "код", Я их использую.

Цитата:
Сообщение от eval Посмотреть сообщение
он не понимает что делает
Как я понимаю, то что я написал:
1) Создаём потоки. Кол-во указываем в Edit1.Text
2) Каждый поток берет адрес из списка
3) Загоняем в Page код страницы (если нет ошибки)
4) Регулярными выражениями вытягиваем со страницы ссылки
5) Добавляем ссылки в конец списка
6) переходим к пункту 2...
chex01 вне форума Ответить с цитированием
Старый 16.04.2013, 23:21   #9
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,430
По умолчанию

Цитата:
Я их использую.
Даже в TestRegExprStudio есть спец. выражение для поиска ссылок ftp:// http:// попробуйте его.
Человек_Борща вне форума Ответить с цитированием
Старый 17.04.2013, 12:35   #10
chex01
Пользователь
 
Аватар для chex01
 
Регистрация: 06.03.2011
Сообщений: 31
Злость

Цитата:
Сообщение от Человек_Борща Посмотреть сообщение
попробуйте его.
Я чётко поставил вопрос. У меня, как я считаю, нет проблем с парсингом ссылок. Проблема подробно описана в первом посте.
Огромная просьба, действительно знающих людей, помочь.
chex01 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
парсинг ссылок сайта Jadson Работа с сетью в Delphi 19 13.05.2012 22:02
Поиск всех внешних ссылок с сайта asale PHP 2 24.04.2012 22:56
Парсинг ссылок сайта demiancz Общие вопросы Delphi 9 27.02.2012 01:00
Парсинг ссылок cashmail PHP 1 01.07.2011 16:39
Возможно ли узнать количество всех внешних ссылок сайта? Dux Работа с сетью в Delphi 1 14.03.2011 17:46