Beispiel #1
0
 /**
  * Timeout перед очередным запросом
  * @param string $url
  * @return bool
  */
 protected function _timeout($url)
 {
     $domain = Uri::getHost($url);
     // пытаемся считать timeout для текущего домена из БД
     try {
         $timeout = $this->_Db->timeout($domain);
     } catch (\Exception $e) {
         $timeout = null;
     }
     try {
         if (!is_float($timeout)) {
             $timeouts = Robots\Instance::get($url, 'crawl-delay', $this->_config['agent']);
             $timeout = is_array($timeouts) && isset($timeouts[0]['value']) ? floatval($timeouts[0]['value']) : 0.0;
             // ставим timeout
             try {
                 $timeout = $this->_Db->timeout($domain, $timeout);
             } catch (\Exception $e) {
             }
         }
         // получаем время последнего запроса
         try {
             $last = $this->_Db->request($domain);
         } catch (\Exception $e) {
             // если ошибка, то делаем вид, что только что сделали запрос
             $last = microtime(true);
         }
         $now = microtime(true);
         // переводим в микросекунды
         $diff = $last - $now + $timeout;
         // смотря что больше текущий момент или последний запрос (он может быть в будущем, т.к. мы резервируем время
         $next = max([$now, $last]);
         if ($diff > 0) {
             $next += $diff;
         }
         // небольшой хак, для того, что другие клиенты считали этот запрос выполенным, иначе может получить пачка
         // с одной задержкой
         $this->_Db->request($domain, $next);
         if ($diff > 0) {
             $sleep = ($next - $now) * 1000000;
             usleep($sleep);
         }
         return true;
     } catch (\Exception $e) {
         return false;
     }
 }
Beispiel #2
0
 /**
  * Загружаем robots txt
  *
  * @param string $url домен или url для загрузки
  * @return string $content содержимое robots
  */
 protected function _request($url, $agent)
 {
     Browser::pack();
     Browser::configure(['agent' => $agent], ['direct' => true, 'exception' => true]);
     $content = Browser::get(Uri::getHost($url) . '/robots.txt');
     Browser::unpack();
     return $content;
 }
Beispiel #3
0
 /**
  * Проверяем индексации url-а
  *
  * @param string $text сайт
  * @param string $region регион
  * @param array $additional массив дополнительных параметорв
  * @throws Exception
  *
  * @return array
  */
 public function isIndexed($text, $region = null, $additional = [])
 {
     $query = is_array($text) ? $text['text'] : $text;
     $domain = is_array($text) && !empty($text['domain']) ? $text['domain'] : null;
     // формируем данные для поиска
     $params = [];
     if (Uri::isValid($query)) {
         $query = Uri::wwwLess(Uri::httpLess($query));
         $params['text'] = 'url:(' . $query . ') | url:(www.' . $query . ')';
     } else {
         $params['text'] = $query;
     }
     $params['region'] = $region;
     // домен
     if (!Uri::isValid($query) && !empty($domain)) {
         $params['text'] .= " site:{$domain}";
     }
     $result = $this->search($params);
     if (!isset($result['total_pages'])) {
         throw new Exception('Не удалось проанализировать выдачу.');
     }
     $domain = $domain ?: Uri::getHost($query);
     $validate = !empty($additional['validate']);
     $urls = array_filter($result['results'], function ($record) use($domain, $validate) {
         if (!empty($domain)) {
             if (!Uri::isSameHostIdna($record->url, $domain, false)) {
                 return false;
             }
         }
         return $validate ? Checker::isValid($record->url, 'text/html') : true;
     });
     return ['indexed' => !empty($urls) && count($urls) > 0, 'urls' => $urls];
 }
Beispiel #4
0
 /**
  * Устанавливаем url для следующего запроса
  *
  * @param string $url
  * @return bool
  */
 public function url($url)
 {
     $this->_url = Uri::toIdn($url);
     // кодируем всё заранее в punycode во избежании путаницы
     return curl_setopt($this->_curl, CURLOPT_URL, $this->_url);
 }