Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: мониторинг позиций сайта по нескольким запросам
 
 автор: Slo_Nik   (23.03.2010 в 14:26)   письмо автору
 
 

Добрый день.
Попытался написать скрипт мониторинга позиций сайта по не скольким запросам, но в конечном итоге не обрабатываются все запросы, а только первый.
За основу взят скрипт из книги "PHP практика создания web-сайтов 2-е издание", ограничился пока мониторингом в системе Google.
вот сам скрипт

<?php 
error_reporting
(E_ALL);
@
set_time_limit(0);
$keyword = array("форум php","web студия Нижний Новгород","форум mysql","фотография");
$site "softtime.ru";
    function 
google($url){
      
// результатирующий массив
      
$result = array();
      
// регулярное выражение
      
$pattern "|<li class=g><h3 class=r><a href=\"([^\"]+)\"[^>]*>(.+)</a>|isU";
      
// загрузка содержимого страницы
      
$content file_get_contents($url);
      
// поиск по регулярному выражению
      
preg_match_all($pattern,$content,$out,PREG_PATTERN_ORDER);
      
// Помещаем результаты в результирующий массив
       
for($i 0$i count($out[1]); $i++){
        
$result[$i]['url'] = $out[1][$i];
        
$result[$i]['name'] = $out[2][$i];
       }
       return 
$result;
    }
function 
search($key$site){
    
$res "";
    
// кол-во просматриваемых страниц
    
$pnum 5;
  for(
$p 0$p $pnum$p++){
      
/* массив адресов с запросами */
      
foreach($key as $v){
       
$url[] = "http://www.google.com/search?rls=ru&q=".urlencode($v)."&start=".($p*$pnum)."";
      }
    
/* поиск по запросам на страницах */
     
for($u 0$u count($url); $u++){
       
$arr google($url[$u]);
       
$res .= "<h3>Запрос № ".($u+1)."</h3>";
       for(
$i 0$i count($arr); $i++){
         if(
strpos($arr[$i]['url'],$site) !== false){
         
$res .= "<a href='".$arr[$i]['url']."'>".$arr[$i]['name']."</a><br>";
         
$res .= "<h5>Позиция ".$site." - ".($p 10 $i)."</h5>";
         return 
$res;
         }
       }
     }
  }
  
$res .= "Сайт не найден";
  return 
$res
}
echo 
search($keyword$site);
?>

вот при таком разкладе позиция выдаётся только по первому запросу "форум php".
если не оформлять выполнение скрипта функцией search, просто вызвать функцию google(), без учёта страниц, то для первой страницы будет выведена информация по всем запросам.
подскажите, пожалуйста, в чём моя ошибка?

  Ответить  
 
 автор: Лена   (23.03.2010 в 16:04)   письмо автору
 
   для: Slo_Nik   (23.03.2010 в 14:26)
 

А var_dump($arr); не делали?
И попробуйте так:
$arr[] = google($url[$u]);

  Ответить  
 
 автор: Slo_Nik   (23.03.2010 в 16:39)   письмо автору
 
   для: Лена   (23.03.2010 в 16:04)
 

$arr[] = google($url[$u]); зацикливает скрипт

var_dump($arr) даёт массив по первому запросу

  Ответить  
 
 автор: Лена   (23.03.2010 в 16:52)   письмо автору
 
   для: Slo_Nik   (23.03.2010 в 16:39)
 

У меня по этому варианту $arr[] = google($url[$u]); ничего не зацикливаеся. Скрипт секунд 5 работает и выдает кучу вариантов по всем запросам. Вернее, заполняется массив $arr.
Вообще-то вам надо логику как-то передумать. Функция внутри цикла, тем более, которая выдает такой большой кусок результата, не очень хорошо...

  Ответить  
 
 автор: Slo_Nik   (23.03.2010 в 17:33)   письмо автору
 
   для: Лена   (23.03.2010 в 16:52)
 

да, массив заполняется, это что то я не так сделал...
но заполняется тоже странно, получается, что выдаёт 3-х(?) массив, в который при каждой новой итерации цикла попадают результаты нового запроса.
хотя не странно, всё так и должно заполняться, но не могу придумать как обойтись без вызова функции в цикле.
вдобавок стало ругаться на строку if(strpos($arr[$i]['url'],$site) !== false){, не определённый индекс url
.....................................................................
с индексом url понятно, но если сделать if(strpos($arr[$u][$i]['url'],$site) !== false) индекс получается определённый, но тогда вся работа обрывается на втором запросе....

  Ответить  
 
 автор: Лена   (23.03.2010 в 21:36)   письмо автору
 
   для: Slo_Nik   (23.03.2010 в 17:33)
 

Я бы здесь вообще сделала одну функцию.
Получили нужный нам контент. Нашли в нем все, что соответствует паттерну. И сразу же здесь, на месте, запихнули бы все найденное в адреса с запросами. А дальше уже на каждой странице проверяем эти запросы. Так, по крайней мере, меньше циклов будет. А то здесь операция "собираем в массив-раскладываем массив" несколько раз повторяется.

  Ответить  
 
 автор: Slo_Nik   (23.03.2010 в 23:05)   письмо автору
 
   для: Лена   (23.03.2010 в 21:36)
 

я тоже подумал о том, что отказаться от функции google(), а сразу всё делать в функции search().
подумаю - отпишусь, что придумал...
вот тут ещё один вопрос не совсем для меня ясный, что означает в адресной строке поисковика "&sa=N"? да и вообще, где можно почитать по тем параметрам, которые передаются в адресной строке?

  Ответить  
 
 автор: Лена   (24.03.2010 в 10:18)   письмо автору
 
   для: Slo_Nik   (23.03.2010 в 23:05)
 

>вот тут ещё один вопрос не совсем для меня ясный, что означает в адресной строке поисковика "&sa=N"?

А где вы это взяли?
У меня адресная строка Google такая, например:
http://www.google.com.ua/search?hl=ru&q=%D1%84%D0%BE%D1%80%D0%BC%D0%B0&meta=&aq=f&oq=

  Ответить  
 
 автор: Slo_Nik   (24.03.2010 в 11:27)   письмо автору
 
   для: Лена   (24.03.2010 в 10:18)
 

http://www.google.com/search?hl=ru&client=opera&hs=dUM&rls=ru&q=....&start=20&sa=N
вот, перейдя на вторую страницу с результатами поиска

  Ответить  
 
 автор: Лена   (24.03.2010 в 11:38)   письмо автору
 
   для: Slo_Nik   (24.03.2010 в 11:27)
 

Набираете любое слово в поиске.
Выдаются результаты.
Внизу результатов есть "Поисковые запросы, связанные с ... (ваше слово)"

И когда нажимаешь на любой связанный запрос, в строке уже &sa=X.
Мне кажется, это разделение по каким-то критериям поиска. Типа подразделов поиска.

  Ответить  
 
 автор: Slo_Nik   (24.03.2010 в 11:53)   письмо автору
 
   для: Лена   (24.03.2010 в 11:38)
 

в разных примерах адрес для поиска по разному составляется, вот и интересно может ли это влиять на работу скрипта мониторинга?
вод два примера из книг авторов
$url = "http://www.google.ru/search?q=...&complete=1&hl=ru&lr=&start=...&sa=N";
$url = "http://www.google.ru/search?hl=ru&q=...&btnG=...&lr="
вот пример из другого источника
$qp = 'http://www.google.ru/search?q=...&hl=ru&lr=&client=firefox-a&rls=org.mozilla:ru:official' ...$n . '&sa=N';

  Ответить  
 
 автор: Slo_Nik   (29.03.2010 в 15:49)   письмо автору
 
   для: Лена   (23.03.2010 в 21:36)
 

вот что получилось

<?php 
/* уровень ошибок */
error_reporting(E_ALL);
/* время выполнения скрипта */
set_time_limit(0);
/* массив запросов */
$key = array("форум php","web студия Нижний Новгород","форум mysql","архив");
/* имя домена */
$site "softtime.ru";
/* функция поиска */
function google($key$site){
/* вспомогательные переменные */
$stop false;// для цикла while 
$n 0// для запросов
$p 0// для страниц
$position 100// кол-во позиций в поиске
/* регулярное выражение */
$pattern "|<li class=g><h3 class=r><a href=\"([^\"]+)\"[^>]*>(.+)</a>|isU";
/* переменная для результатов */
$res "";
/* обрабатываем массив с запросами */
foreach($key as $k => $v){
$q[] = urlencode($v);
}
    
$res .= "<h2><font color='red'>Google</font></h2>";
     
/* начало цикла while */
     
while(!$stop){
            
$page $p*10;// подсчёт страниц
            /* адрес поискового запроса */
            
$url "http://www.google.com/search?rls=ru&q=".$q[$n]."&start=".$page."&sa=N";
            
/* получаем содержимое текущей страницы */
            
$contents file_get_contents($url);
            
/* поиск согласно регулярному выражению */
            
preg_match_all($pattern,$contents,$out,PREG_PATTERN_ORDER);
            
/* перебираем часть массива с url */
            
foreach($out[1] as $k => $u)//{
 /* если в url присутствует имя домена - формируем результат */
 
if(strpos($u $site) !== false){
 
/* результаты */
$res .= "<h4><font color='green'>Запрос - \"".urldecode($q[$n])."\"</font></h4>";
$res .= "<a href='".$u."'>".$out[2][$k]."</a><br>";
$res .= "<h5><font color='blue'>Позиция - </font><font color='red'>".($k $page 2)."</font></h5>";
$res .= "<a href='".$url."'>Страница Google</a><hr>";
 }
            
//}     
        
$n++; /* sleep(3); */ /* пауза между запросами */
        /* echo $n." - \$n bottom<br>"; */
        
if($n >= count($q)){/* $stop = true; */ $n 0$p++; /* sleep(5) ;*//* пауза между страницами */}
      if(
$page $position){ break; $stop true;}
     }
// завершение цикла while        
return $res;
}
echo 
google($key$site);
?>

теперь возник вопрос по поводу подсчёта позиций
в строке

<?php 
$res 
.= "<h5><font color='blue'>Позиция - </font><font color='red'>".($k $page 2)."</font></h5>";
?>

цифра "2" берётся из расчёта того, что $k(ключ массива) начинается с "0" и если сравнить просто с запросом через браузер, то например по запросу "форум php" позиция softtime будет "5", у меня же при таком подсчёте показывает "4", остальные позиции по запросам больше на "1" чем если делать запрос через браузер. вот как сделать так, что бы позиции совпадали?
взял к примеру работу ещё одного скрипта, там позиция softtime по запросу "форум php" определяется как "6".
и по поводу пауз между запросами и самими старницами на строках

<?php 
$n
++; /* sleep(3); */ /* пауза между запросами */

// и 

if($n >= count($q)){/* $stop = true; */ $n 0$p++; /* sleep(5) ;*//* пауза между страницами */}
?>

если их раскомментировать, то скрипт естественно гораздо дольше выполняется. вопрос в том, насколько нужны эти паузы? в поисках по инету, я видел рекомендации делать такие паузы. как это может повлиять на работу скрипта с поисковыми системами?
и вообще хотельсь услышать замечания по выполнению кода.

p.s. если делать для других поисковых систем, то думаю просто менять значение $url и вызовы функций делать в одной отдельной через switch или лучше просто через switch сделать вызов функций?

  Ответить  
 
 автор: Лена   (29.03.2010 в 17:14)   письмо автору
 
   для: Slo_Nik   (29.03.2010 в 15:49)
 

Делаешь запрос в гугле на любое слово. На первой странице результатов гет-параметр start вообще не передается. На второй странице start=10, на третьей start=20 и т.д..
Т.е. в $url надо это учесть. У тебя будет тогда как-то так:
if($page!=0)
$start = "&start=".$page.";
else
$start = '';

Если для нескольких систем, надо сделать так, чтобы не пришлось менять $url каждый раз.
Я бы просчитала все варианты сразу, например, названия можно в массив забить, а после:
switch($mode){
case 'google':
$url = "";
break;
case 'yandex':
$url = "";
break;
}

Или
switch($_SERVER['SERVER_NAME']) и т.д.

По остальному вечером отпишусь.

  Ответить  
 
 автор: Slo_Nik   (29.03.2010 в 17:44)   письмо автору
 
   для: Лена   (29.03.2010 в 17:14)
 

>Если для нескольких систем, надо сделать так, чтобы не пришлось менять $url каждый раз

я тоже так думал, но опять же, создавать ещё один массив... хотя так можно сократить код, действительно будет одна функция.

>Делаешь запрос в гугле на любое слово. На первой странице результатов гет-параметр start вообще не передается. На второй странице start=10, на третьей start=20 и т.д.

может тогда сделать так

<?php
if($p != 0){
 
$page $p 10;
 
$start "&start=".$page"";
}
else{
 
$start "";
}

ведь $page считается исходя из значения $p

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования