@@ -1,17 +1,30 @@
 
		
	
		
			
				package   searchengine.services ;  
		
	
		
			
				 
		
	
		
			
				import   lombok.RequiredArgsConstructor ;  
		
	
		
			
				import   org.jsoup.HttpStatusException ;  
		
	
		
			
				import   org.jsoup.Jsoup ;  
		
	
		
			
				import   org.jsoup.nodes.Document ;  
		
	
		
			
				import   org.slf4j.Logger ;  
		
	
		
			
				import   org.slf4j.LoggerFactory ;  
		
	
		
			
				import   org.springframework.dao.DataIntegrityViolationException ;  
		
	
		
			
				import   org.springframework.stereotype.Service ;  
		
	
		
			
				import   org.springframework.transaction.annotation.Isolation ;  
		
	
		
			
				import   org.springframework.transaction.annotation.Propagation ;  
		
	
		
			
				import   org.springframework.transaction.annotation.Transactional ;  
		
	
		
			
				import   searchengine.config.SitesList ;  
		
	
		
			
				import   searchengine.model.Link ;  
		
	
		
			
				import   searchengine.model.SiteEntity ;  
		
	
		
			
				import   searchengine.model.PageEntity ;  
		
	
		
			
				import   searchengine.model.StatusType ;  
		
	
		
			
				import   searchengine.repository.PageRepository ;  
		
	
		
			
				import   searchengine.repository.SiteRepository ;  
		
	
		
			
				 
		
	
		
			
				import   java.net.URI ;  
		
	
		
			
				import   java.net.URISyntaxException ;  
		
	
		
			
				import   java.net.URLEncoder ;  
		
	
		
			
				import   java.nio.charset.StandardCharsets ;  
		
	
		
			
				import   java.u til.Random  ;  
		
	
		
			
				import   java.time.LocalDateTime  ;  
		
	
		
			
				import   java.util.HashSet ;  
		
	
		
			
				import   java.util.Set ;  
		
	
		
			
				import   java.util.concurrent.ConcurrentHashMap ;  
		
	
		
			
				import   java.util.regex.Pattern ;  
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -19,79 +32,164 @@ import java.util.regex.Pattern;
 
		
	
		
			
				@Service  
		
	
		
			
				@RequiredArgsConstructor  
		
	
		
			
				public   class  IndexingServiceImpl   implements   IndexingService   {  
		
	
		
			
				     private   static   final   Logger   logger   =   LoggerFactory . getLogger ( IndexingServiceImpl . class ) ;  
		
	
		
			
				     private   boolean   indexingIsRunning   =   false ;  
		
	
		
			
				     private   final   SitesList   sitesList ;  
		
	
		
			
				     private   final   Random   random   =   new   Random ( ) ;  
		
	
		
			
				     private   final   SiteRepository   siteRepository ;  
		
	
		
			
				     private   final   PageRepository   pageRepository ;  
		
	
		
			
				 
		
	
		
			
				     @Override  
		
	
		
			
				     @Transactional ( propagation   =   Propagation . REQUIRED ,   isolation   =   Isolation . READ_COMMITTED ,   noRollbackFor   =   Exception . class )  
		
	
		
			
				     public   void   startIndexing ( )   {  
		
	
		
			
				         if   ( indexingIsRunning )   {  
		
	
		
			
				             System . out . println ( " Индексация уже запущена " ) ;  
		
	
		
			
				             logger . info ( " Индексация уже запущена " ) ;  
		
	
		
			
				             return ;  
		
	
		
			
				         }  
		
	
		
			
				         indexingIsRunning   =   true ;  
		
	
		
			
				 
		
	
		
			
				         // Выводим список сайтов для индексации  
		
	
		
			
				         System . out . println ( " Список сайтов для индексации: " ) ;  
		
	
		
			
				         logger . info ( " Список сайтов для индексации: " ) ;  
		
	
		
			
				         sitesList . getSites ( ) . forEach ( site   - >  
		
	
		
			
				                 System . out . println ( " URL:  "   +   site . getUrl ( )   +   " , Название:  "   +   site . getName ( ) )  
		
	
		
			
				                 logger . info ( " URL: {}, Название: {} " ,   site . getUrl ( ) ,   site . getName ( ) )  
		
	
		
			
				         ) ;  
		
	
		
			
				 
		
	
		
			
				         // Начинаем парсинг первого сайта  
		
	
		
			
				         String   startUrl   =   sitesList . getSites ( ) . get ( 0 ) . getUrl ( ) ;  
		
	
		
			
				         String   siteName   =   sitesList . getSites ( ) . get ( 0 ) . getName ( ) ;  
		
	
		
			
				         String   startUrl   =   sitesList . getSites ( ) . get ( 1 ) . getUrl ( ) ;  
		
	
		
			
				         String   siteName   =   sitesList . getSites ( ) . get ( 1 ) . getName ( ) ;  
		
	
		
			
				 
		
	
		
			
				         System . out . println ( " Начинаем парсинг сайта "   +    siteName   +   "  ( "   +   startUrl   +   " ) " ) ;  
		
	
		
			
				         logger . info ( " Начинаем парсинг сайта {} ({}) " ,    siteName ,   startUrl ) ;  
		
	
		
			
				 
		
	
		
			
				         Set < URI >   visitedLinks   =   ConcurrentHashMap . newKeySet ( ) ;   // Н а б о р   
		
	
		
			
				         Set < Link >   allLinks   =   ConcurrentHashMap . newKeySet ( ) ;   // Н а б о р   
		
	
		
			
				 
		
	
		
			
				         try   {  
		
	
		
			
				             URI   startUri   =   new   URI ( startUrl ) ;  
		
	
		
			
				             System . out . printf ( " \ n === Начало индексации %s (%s) === \ n " ,   siteName ,   startUri ) ;  
		
	
		
			
				             logger . info ( " === Начало индексации {} ({}) ===  " ,   siteName ,   startUri ) ;  
		
	
		
			
				 
		
	
		
			
				             // Удаляем существующие данные по этому сайту  
		
	
		
			
				             SiteEntity   site   =   siteRepository . findByUrl ( startUrl ) ;  
		
	
		
			
				             if   ( site   ! =   null )   {  
		
	
		
			
				                 logger . info ( " Найден существующий SiteEntity с  " ,   site . getId ( ) ) ;  
		
	
		
			
				                 pageRepository . deleteBySite ( site ) ;  
		
	
		
			
				                 logger . info ( " Удалены все PsgeEntity для SiteEntity с  " ,   site . getId ( ) ) ;  
		
	
		
			
				                 siteRepository . delete ( site ) ;  
		
	
		
			
				                 logger . info ( " Удален SiteEntity с  " ,   site . getId ( ) ) ;  
		
	
		
			
				             }  
		
	
		
			
				 
		
	
		
			
				             // Создаем новую запись в таблице site с о   
		
	
		
			
				             site   =   new   SiteEntity ( ) ;  
		
	
		
			
				             site . setName ( siteName ) ;  
		
	
		
			
				             site . setUrl ( startUrl ) ;  
		
	
		
			
				             site . setStatus ( StatusType . INDEXING ) ;  
		
	
		
			
				             site . setStatus_time ( LocalDateTime . now ( ) ) ;  
		
	
		
			
				             site   =   siteRepository . save ( site ) ;   // Сохраняем и обновляем объект  
		
	
		
			
				 
		
	
		
			
				             logger . info ( " Создана новая запись в таблице site с  " ,   site . getId ( ) ) ;  
		
	
		
			
				 
		
	
		
			
				             Link   rootLink   =   new   Link ( startUri ,   null ) ;   // Создаем корневой Link  
		
	
		
			
				             parse ( rootLink ,   visitedLinks ) ;   // Запуск парсинга  
		
	
		
			
				             allLinks . add ( rootLink ) ;   // Добавляем корневую ссылку во множество всех ссылок  
		
	
		
			
				             parse ( rootLink ,   site ,   visitedLinks ,   allLinks ) ;   // Запуск парсинга  
		
	
		
			
				 
		
	
		
			
				             // Обновляем статус сайта на INDEXED  
		
	
		
			
				             site . setStatus ( StatusType . INDEXED ) ;  
		
	
		
			
				             site . setStatus_time ( LocalDateTime . now ( ) ) ;  
		
	
		
			
				             siteRepository . save ( site ) ;  
		
	
		
			
				 
		
	
		
			
				             logger . info ( " Статус сайта обновлен на INDEXED с  " ,   site . getId ( ) ) ;  
		
	
		
			
				         }   catch   ( URISyntaxException   e )   {  
		
	
		
			
				             System . out . println ( " Некорректный URL:  "   +   startUrl ) ;  
		
	
		
			
				             logger . error ( " Некорректный URL: {}  " ,   startUrl ,   e ;  
		
	
		
			
				             handleIndexingError ( startUrl ,   " Некорректный URL:  "   +   startUrl ) ;  
		
	
		
			
				         }   catch   ( InterruptedException   e )   {  
		
	
		
			
				             System . out . println ( " Индексация была прервана:  "   +   e . getMessage ( ) ) ;  
		
	
		
			
				             Thread . currentThread ( ) . interrupt ( ) ;  
		
	
		
			
				             logger . error ( " Индексация была прервана: {}  " ,   e . getMessage ( ) ,   e ;  
		
	
		
			
				             handleIndexingError ( startUrl ,   " Индексация была прервана:  "   +   e . getMessage ( ) ) ;  
		
	
		
			
				         }   catch   ( Exception   e )   {  
		
	
		
			
				             logger . error ( " Произошла ошибка при индексации: {} " ,   e . getMessage ( ) ,   e ) ;  
		
	
		
			
				             handleIndexingError ( startUrl ,   " Произошла ошибка при индексации:  "   +   e . getMessage ( ) ) ;  
		
	
		
			
				         }   finally   {  
		
	
		
			
				             indexingIsRunning   =   false ;  
		
	
		
			
				             System . out . println ( " \ n === Индексация завершена ===" ) ;  
		
	
		
			
				             System . out . println ( " В с е г о "   +   visitedLinks . size ( ) ) ;  
		
	
		
			
				             logger . info ( " === Индексация завершена === " ) ;  
		
	
		
			
				             logger . info ( " В с е г о {} " ,   visitedLinks . size ( ) ) ;  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				 
		
	
		
			
				     private   void   parse ( Link   link ,   Set < URI >   visited Links )   throws   InterruptedException   {  
		
	
		
			
				     private   void   parse ( Link   link ,   SiteEntity   site ,   Set < URI >   visitedLinks ,   Set < Link >   all Links )   throws   InterruptedException   {  
		
	
		
			
				         // Добавляем текущий URL в visitedLinks до начала обработки  
		
	
		
			
				         if   ( ! visitedLinks . add ( link . uri ( ) ) )   {  
		
	
		
			
				             logger . debug ( " URL уже был обработан: {} " ,   link . uri ( ) ) ;  
		
	
		
			
				             return ;   // Если URL уже был обработан, выходим  
		
	
		
			
				         }  
		
	
		
			
				 
		
	
		
			
				         // Обновляем время статуса  
		
	
		
			
				         site . setStatus_time ( LocalDateTime . now ( ) ) ;  
		
	
		
			
				         siteRepository . save ( site ) ;  
		
	
		
			
				 
		
	
		
			
				         // Задержка для соблюдения правил robots.txt  
		
	
		
			
				         Thread . sleep ( 50   +   random . nextInt ( 150 ) ) ;  
		
	
		
			
				        System . out . println ( " Парсим страницу:  "   +   link . uri (  ) ) ;  
		
	
		
			
				         try   {  
		
	
		
			
				             Thread . sleep ( ( long )   ( 50   +   ( Math . random ( )   *   150 )  ) ) ;  
		
	
		
			
				         }   catch   ( InterruptedException   e )   {  
		
	
		
			
				             logger . error ( " Парсинг был прерван: {} " ,   e . getMessage ( ) ,   e ) ;  
		
	
		
			
				             Thread . currentThread ( ) . interrupt ( ) ;  
		
	
		
			
				             throw   new   RuntimeException ( " Парсинг был прерван:  "   +   e . getMessage ( ) ,   e ) ;  
		
	
		
			
				         }  
		
	
		
			
				 
		
	
		
			
				         logger . info ( " Парсим страницу: {} " ,   link . uri ( ) ) ;  
		
	
		
			
				 
		
	
		
			
				         // Добавляем дочерние ссылки  
		
	
		
			
				         addChildLinks ( link ,   visitedLinks ) ;  
		
	
		
			
				         try   {  
		
	
		
			
				             addChildLinks ( link ,   site ,   visitedLinks ,   allLinks ) ;  
		
	
		
			
				         }   catch   ( Exception   e )   {  
		
	
		
			
				             logger . error ( " Ошибка при добавлении дочерних ссылок для {}: {} " ,   link . uri ( ) ,   e . getMessage ( ) ,   e ) ;  
		
	
		
			
				             throw   e ;   // Пробрасываем исключение дальше  
		
	
		
			
				         }  
		
	
		
			
				 
		
	
		
			
				         // Рекурсивно обрабатываем дочерние ссылки  
		
	
		
			
				         link . children ( ) . forEach ( child   - >   {  
		
	
		
			
				             try   {  
		
	
		
			
				                 parse ( child ,   visitedLinks ) ;  
		
	
		
			
				            }   catch   ( InterruptedException   e )   {   
		
	
		
			
				                 Thread . currentThread ( ) . interrupt ( ) ;  
		
	
		
			
				                throw   new   RuntimeException  ( " Парсинг был прерван:  "   +   e . getMessage ( ) ) ;  
		
	
		
			
				         for   ( Link   child   :   new   HashSet < > ( allLinks ) )   {   // Создаем копию множества для итерации  
		
	
		
			
				             if   ( ! visitedLinks . contains ( child . uri ( ) ) )   {  
		
	
		
			
				                 try   {  
		
	
		
			
				                     parse ( child ,   site ,   visitedLinks ,   allLinks ) ;   
		
	
		
			
				                 }   catch   ( InterruptedException   e )   {  
		
	
		
			
				                     logger . error  ( " Парсинг был прерван: {}  " ,   e . getMessage ( ) ,   e ;  
		
	
		
			
				                     Thread . currentThread ( ) . interrupt ( ) ;  
		
	
		
			
				                     throw   new   RuntimeException ( " Парсинг был прерван:  "   +   e . getMessage ( ) ,   e ) ;  
		
	
		
			
				                 }   catch   ( Exception   e )   {  
		
	
		
			
				                     logger . error ( " Произошла ошибка при парсинге {}: {} " ,   child . uri ( ) ,   e . getMessage ( ) ,   e ) ;  
		
	
		
			
				                 }  
		
	
		
			
				             }  
		
	
		
			
				         } ) ;  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				 
		
	
		
			
				     private   void   addChildLinks ( Link   link ,   Set < URI >   visited Links )   {  
		
	
		
			
				     private   void   addChildLinks ( Link   link ,   SiteEntity   site ,   Set < URI >   visitedLinks ,   Set < Link >   all Links )   {  
		
	
		
			
				         try   {  
		
	
		
			
				             logger . debug ( " Пытаемся получить страницу: {} " ,   link . uri ( ) ) ;  
		
	
		
			
				             Document   document   =   Jsoup . connect ( link . uri ( ) . toString ( ) )  
		
	
		
			
				                     . userAgent ( " Mozilla/5.0 " )  
		
	
		
			
				                     . referrer ( " https://www.google.com " )  
		
	
		
			
				                     . get ( ) ;  
		
	
		
			
				             logger . debug ( " Страница успешно получена: {} " ,   link . uri ( ) ) ;  
		
	
		
			
				 
		
	
		
			
				             // Проверяем, что site не равен null  
		
	
		
			
				             if   ( site   = =   null )   {  
		
	
		
			
				                 throw   new   IllegalStateException ( " SiteEntity не может быть null " ) ;  
		
	
		
			
				             }  
		
	
		
			
				 
		
	
		
			
				             // Получаем путь  
		
	
		
			
				             String   path   =   link . uri ( ) . getPath ( ) ;  
		
	
		
			
				             if   ( path   = =   null   | |   path . isEmpty ( ) )   {  
		
	
		
			
				                 path   =   " / " ;   // Устанавливаем корневой путь, если он пустой  
		
	
		
			
				             }  
		
	
		
			
				             PageEntity   existingPage   =   pageRepository . findBySiteAndPath ( site ,   path ) ;  
		
	
		
			
				             if   ( existingPage   = =   null )   {  
		
	
		
			
				                 // Сохраняем страницу в базу данных  
		
	
		
			
				                 PageEntity   page   =   new   PageEntity ( ) ;  
		
	
		
			
				                 page . setSite ( site ) ;   // Устанавливаем связь с   
		
	
		
			
				                 page . setPath ( path ) ;  
		
	
		
			
				                 page . setCode ( document . connection ( ) . response ( ) . statusCode ( ) ) ;  
		
	
		
			
				                 page . setContent ( document . outerHtml ( ) ) ;  
		
	
		
			
				                 pageRepository . save ( page ) ;  
		
	
		
			
				                 logger . info ( " Сохранена страница: {} " ,   link . uri ( ) ) ;  
		
	
		
			
				             }   else   {  
		
	
		
			
				                 logger . warn ( " Страница уже существует: {} " ,   link . uri ( ) ) ;  
		
	
		
			
				             }  
		
	
		
			
				 
		
	
		
			
				             document . select ( " a[href] " ) . forEach ( element   - >   {  
		
	
		
			
				                 String   hrefStr   =   element . attr ( " href " ) . strip ( ) ;  
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -109,34 +207,46 @@ public class IndexingServiceImpl implements IndexingService {
 
		
	
		
			
				 
		
	
		
			
				                     // Проверяем, что ссылка корректна  
		
	
		
			
				                     if   ( isCorrectUrl ( link . uri ( ) ,   href ,   visitedLinks ) )   {  
		
	
		
			
				                         l ink. addChild ( href ) ;   // Используем метод addChild из класса Link  
		
	
		
			
				                         L ink  childLink   =   new   Link ( href ,   link ) ;  
		
	
		
			
				                         allLinks . add ( childLink ) ;   // Добавляем дочернюю ссылку в список всех ссылок  
		
	
		
			
				                         logger . debug ( " Добавлена дочерняя ссылка: {} " ,   childLink . uri ( ) ) ;  
		
	
		
			
				                     }  
		
	
		
			
				                 }   catch   ( Exception   e )   {  
		
	
		
			
				                     // Игнорируем некорректные URL без вывода сообщений  
		
	
		
			
				                     logger . warn ( " Некорректная ссылка: {} " ,   hrefStr ,   e ) ;  
		
	
		
			
				                 }  
		
	
		
			
				             } ) ;  
		
	
		
			
				         }   catch   ( HttpStatusException   e )   {  
		
	
		
			
				             logger . warn ( " HTTP ошибка при добавлении дочерних ссылок: Status={}, URL={} " ,   e . getStatusCode ( ) ,   e . getUrl ( ) ) ;  
		
	
		
			
				         }   catch   ( DataIntegrityViolationException   e )   {  
		
	
		
			
				             logger . error ( " Ошибка целостности данных при сохранении страницы: {} " ,   e . getMessage ( ) ) ;  
		
	
		
			
				             throw   e ;   // Пробрасываем исключение дальше  
		
	
		
			
				         }   catch   ( Exception   e )   {  
		
	
		
			
				             // Игнорируем ошибки без вывода сообщений  
		
	
		
			
				             logger . error ( " Ошибка при добавлении дочерних ссылок: {} " ,   e . getMessage ( ) ,   e ) ;  
		
	
		
			
				             throw   new   RuntimeException ( " Ошибка при добавлении дочерних ссылок " ,   e ) ;  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				 
		
	
		
			
				     private   URI   normalizeUri ( URI   href )   {  
		
	
		
			
				         try   {  
		
	
		
			
				             String   path   =   href . getPath ( ) ;   // Получаем путь  
		
	
		
			
				             if   ( path   = =   null )   {  
		
	
		
			
				                 path   =   " " ;   // Если путь равен null, заменяем на пустую строку   
		
	
		
			
				             String   path   =   href . getPath ( ) ;  
		
	
		
			
				             if   ( path   = =   null   | |   path . isEmpty ( ) )   {  
		
	
		
			
				                 path   =   " / ;   // Устанавливаем корневой путь, если он пустой   
		
	
		
			
				             }   else   {  
		
	
		
			
				                 path   =   path . replaceAll ( " /+$ " ,   " " ) ;   // Убираем завершающие слэши  
		
	
		
			
				                 path   =   path . replaceAll ( " /+$ " ,   " " ) ;  
		
	
		
			
				                 if   ( path . isEmpty ( ) )   {  
		
	
		
			
				                     path   =   " / " ;  
		
	
		
			
				                 }  
		
	
		
			
				             }  
		
	
		
			
				             return   new   URI (  
		
	
		
			
				                     href . getScheme ( ) ,  
		
	
		
			
				                     href . getAuthority ( ) ,  
		
	
		
			
				                     path ,   // Используем обработанный путь  
		
	
		
			
				                     path ,  
		
	
		
			
				                     null ,  
		
	
		
			
				                     href . getFragment ( )  
		
	
		
			
				             ) ;  
		
	
		
			
				         }   catch   ( URISyntaxException   e )   {  
		
	
		
			
				             return   href ;   // В   
		
	
		
			
				             logger . warn ( " Некорректный URL: {} " ,   href ,   e ) ;  
		
	
		
			
				             return   href ;  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -144,11 +254,13 @@ public class IndexingServiceImpl implements IndexingService {
 
		
	
		
			
				         // Проверка на некорректные протоколы  
		
	
		
			
				         String   hrefStr   =   href . toString ( ) ;  
		
	
		
			
				         if   ( hrefStr . startsWith ( " javascript: " )   | |   hrefStr . startsWith ( " mailto: " )   | |   hrefStr . startsWith ( " tel: " ) )   {  
		
	
		
			
				             logger . debug ( " Некорректный протокол: {} " ,   hrefStr ) ;  
		
	
		
			
				             return   false ;  
		
	
		
			
				         }  
		
	
		
			
				 
		
	
		
			
				         // Проверка на принадлежность тому же домену  
		
	
		
			
				         if   ( href . getHost ( )   = =   null   | |   ! href . getHost ( ) . equals ( baseUri . getHost ( ) ) )   {  
		
	
		
			
				             logger . debug ( " Ссылка не принадлежит тому же домену: {} " ,   hrefStr ) ;  
		
	
		
			
				             return   false ;  
		
	
		
			
				         }  
		
	
		
			
				 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -156,10 +268,25 @@ public class IndexingServiceImpl implements IndexingService {
 
		
	
		
			
				         Pattern   patternNotFile   =   Pattern . compile ( " ( \\ S+( \\ .(?i)(jpg|png|gif|bmp|pdf|php|doc|docx|rar))$) " ) ;  
		
	
		
			
				         Pattern   patternNotAnchor   =   Pattern . compile ( " #([ \\ w \\ -]+)?$ " ) ;  
		
	
		
			
				         if   ( href . isOpaque ( )   | |   patternNotFile . matcher ( hrefStr ) . find ( )   | |   patternNotAnchor . matcher ( hrefStr ) . find ( ) )   {  
		
	
		
			
				             logger . debug ( " Ссылка на файл или якорь: {} " ,   hrefStr ) ;  
		
	
		
			
				             return   false ;  
		
	
		
			
				         }  
		
	
		
			
				 
		
	
		
			
				         // Проверка на уже посещенные ссылки  
		
	
		
			
				         return   ! visitedLinks . contains ( href ) ;  
		
	
		
			
				     }  
		
	
		
			
				 
		
	
		
			
				     private   void   handleIndexingError ( String   startUrl ,   String   errorMessage )   {  
		
	
		
			
				         SiteEntity   site   =   siteRepository . findByUrl ( startUrl ) ;  
		
	
		
			
				         if   ( site   ! =   null )   {  
		
	
		
			
				             site . setStatus ( StatusType . FAILED ) ;  
		
	
		
			
				             site . setLast_error ( errorMessage ) ;  
		
	
		
			
				             site . setStatus_time ( LocalDateTime . now ( ) ) ;  
		
	
		
			
				             siteRepository . save ( site ) ;  
		
	
		
			
				             logger . error ( " Ошибка индексации для сайта {}: {} " ,   startUrl ,   errorMessage ) ;  
		
	
		
			
				         }   else   {  
		
	
		
			
				             logger . error ( " Н е " ,   startUrl ) ;  
		
	
		
			
				         }  
		
	
		
			
				         logger . error ( errorMessage ) ;  
		
	
		
			
				     }  
		
	
		
			
				}