|
|
|
| Добрый день.
Попытался написать скрипт мониторинга позиций сайта по не скольким запросам, но в конечном итоге не обрабатываются все запросы, а только первый.
За основу взят скрипт из книги "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(), без учёта страниц, то для первой страницы будет выведена информация по всем запросам.
подскажите, пожалуйста, в чём моя ошибка? | |
|
|
|
|
|
|
|
для: Slo_Nik
(23.03.2010 в 14:26)
| | А var_dump($arr); не делали?
И попробуйте так:
$arr[] = google($url[$u]); | |
|
|
|
|
|
|
|
для: Лена
(23.03.2010 в 16:04)
| | $arr[] = google($url[$u]); зацикливает скрипт
var_dump($arr) даёт массив по первому запросу | |
|
|
|
|
|
|
|
для: Slo_Nik
(23.03.2010 в 16:39)
| | У меня по этому варианту $arr[] = google($url[$u]); ничего не зацикливаеся. Скрипт секунд 5 работает и выдает кучу вариантов по всем запросам. Вернее, заполняется массив $arr.
Вообще-то вам надо логику как-то передумать. Функция внутри цикла, тем более, которая выдает такой большой кусок результата, не очень хорошо... | |
|
|
|
|
|
|
|
для: Лена
(23.03.2010 в 16:52)
| | да, массив заполняется, это что то я не так сделал...
но заполняется тоже странно, получается, что выдаёт 3-х(?) массив, в который при каждой новой итерации цикла попадают результаты нового запроса.
хотя не странно, всё так и должно заполняться, но не могу придумать как обойтись без вызова функции в цикле.
вдобавок стало ругаться на строку if(strpos($arr[$i]['url'],$site) !== false){, не определённый индекс url
.....................................................................
с индексом url понятно, но если сделать if(strpos($arr[$u][$i]['url'],$site) !== false) индекс получается определённый, но тогда вся работа обрывается на втором запросе.... | |
|
|
|
|
|
|
|
для: Slo_Nik
(23.03.2010 в 17:33)
| | Я бы здесь вообще сделала одну функцию.
Получили нужный нам контент. Нашли в нем все, что соответствует паттерну. И сразу же здесь, на месте, запихнули бы все найденное в адреса с запросами. А дальше уже на каждой странице проверяем эти запросы. Так, по крайней мере, меньше циклов будет. А то здесь операция "собираем в массив-раскладываем массив" несколько раз повторяется. | |
|
|
|
|
|
|
|
для: Лена
(23.03.2010 в 21:36)
| | я тоже подумал о том, что отказаться от функции google(), а сразу всё делать в функции search().
подумаю - отпишусь, что придумал...
вот тут ещё один вопрос не совсем для меня ясный, что означает в адресной строке поисковика "&sa=N"? да и вообще, где можно почитать по тем параметрам, которые передаются в адресной строке? | |
|
|
|
|
|
|
|
для: 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= | |
|
|
|
|
|
|
|
для: Лена
(24.03.2010 в 10:18)
| | http://www.google.com/search?hl=ru&client=opera&hs=dUM&rls=ru&q=....&start=20&sa=N
вот, перейдя на вторую страницу с результатами поиска | |
|
|
|
|
|
|
|
для: Slo_Nik
(24.03.2010 в 11:27)
| | Набираете любое слово в поиске.
Выдаются результаты.
Внизу результатов есть "Поисковые запросы, связанные с ... (ваше слово)"
И когда нажимаешь на любой связанный запрос, в строке уже &sa=X.
Мне кажется, это разделение по каким-то критериям поиска. Типа подразделов поиска. | |
|
|
|
|
|
|
|
для: Лена
(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'; | |
|
|
|
|
|
|
|
для: Лена
(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 сделать вызов функций? | |
|
|
|
|
|
|
|
для: 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']) и т.д.
По остальному вечером отпишусь. | |
|
|
|
|
|
|
|
для: Лена
(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 | |
|
|
|