Если Seoquake не показывает количество страниц Яндекса

Вот незадача: один из моих любимых плагинов для Mozilla FireFox - SEOQUAKE , перестал показывать количество страниц в Яндексе. Я, конечно, понимаю, что виноват сам Yandex, постоянно меняющий теги внутри страниц с выдачей результатов, но и его можно понять: всё меняется и Яндекс не исключение.

Так в чем же причина и как решить проблему? Заглянем вовнутрь плагина.

Открываем Preferences, вкладка Parameters, выбираем строчку "Yandex index" И нажимаем кнопку Edit (она такая одна). И видим вот это:

[NAME]=Yandex index
[TITLE]=I
[URL_R]=http://www.yandex.ru/yandsearch?serverurl={domain|encode}
[REGEXP]=<strong class="l">[^<]+<br>(\d+)([^<]+)</strong>

Меняем строку [REGEXP] :

[REGEXP]=<strong class="b-head-logo__text">[^<]*<br>(\d+&nbsp;(.{3}\.)*(.{3}\s)*)

Всё. Можно закрывать. Теперь ToolBar снова показывает количество страничек в Яше.

UPD (12.11.2010 )Безусловно, можно было подождать 9 дней до обновления SEOQUAKE, но, потренировать свои навыки в этом деле считаю никогда не лишне. Поэтому

Для любознательных продолжим.

А как оно работает? Что, делать, если завтра война снова Яша что-то поменяет?  Всё это можно всегда поправить.

Нас интересует строчка [REGEXP], потому, что она отвечает за парсинг Яша-странички. Начинаем исследовать причинно следственную связь. Итак,  открываем окно FF, а в нем открываем какой-либо сайт. Теперь тыкаем мышей в то место на панели SEOQUAKE, где Яша показывает ЯI:0 (тут любая цифра, обозначающая количество проидексированных страничек). Нажимаем левую кнопку. Открывается новая вкладка с адресом типа: http://yandex.ru/yandsearch?serverurl=hoster01.ru&lr=193. Переходим в нее. Нажимаем CTRL-U и смотрим исходный текст. Задача: найти место, где находятся цифры с количеством, а именно слова
Нашлось
188 ответов

Вот эту цифру 188 мы и должны выделить  из всего остального мусора. 

В HTML виде это будет

<strong class="b-head-logo__text">
Нашлось<br>188&nbsp;ответов
</strong>

Это и есть наша искомая строка.

Однако, не всё так просто. Варианты ответов Яши могут быть такими:

Нашлось
291 ответ

или
392 ответа

или

17 тыс. ответов

или
1 млн ответов

Как видим, нам необходимо выделить не только цифры, а цифры вместе со следующим словом тыс. или млн.

Для начала найдем то, от чего будем отталкиваться при поиске "искомой строки".

<strong class="b-head-logo__text">  - уникальный ключ во всем тексте, он и будет обозначать начало нашей искомой строки. То есть, сначала мы находим в тексте этот ключ, а затем начинаем выделять следующие за ним цифры и слова.

Cоставляем строку для REGEXP таким образом, чтобы он полностью совпал с искомой строкой. Думаю, она должна быть такой:

<strong class="b-head-logo__text">[^<]*<br>(\d+&nbsp;(.{3}\.)*(.{3}\s)*)

где

  1. <strong class="b-head-logo__text"> - непосредственный набор литералов, совпадающий с началом искомой строки;
  2. [^<]* - любое количество (включая их отсутсвие) любых литерало, кроме левой угловой скобки "<". Совпадет со словом Нашлось и любым другим словом, которое Яша может тут вписать;
  3. <br> - набор литералов, непосредственно предшествующий цифрам (это для HTML они являются тэгом, а для нас - кучка значков-литералов) ;
  4. \d+ - цифры
  5. &nbsp; - набор симвлов после цифр
  6. (.{3}\.)* - три любых символа с точкой на конце (тыс.), либо их отсутствие
  7. (.{3}\s)* - три любых символа с пробелом на конце (млн), либо их отсутствие
  8. начиная с 4 пункта до конца берем в скобки, чтобы сохранить результат в переменной (получится, например, 17&nbsp;тыс.)

Для отладки я использовал запущенный сервер Denwer, сохраненный файл с результатами обработки запроса Яндексом, содержащий искомую строку yandsearch.htm. И вот такой php скрипт:

<?php

 $cont = CurlPage('http://test/yandsearch.htm');
// не забываем заключать шаблон поиска в косые 
 echo preg_match ('/<strong class="b-head-logo__text">[^<]*<br>(\d+&nbsp;(?:.{3}\.*\s))/', $cont, $complet), '<br>'; 
 
 // echo  $cont;
 echo  'the text that matched the full pattern - ', $complet[0], '<br>';
 echo  'digit - ', $complet[1], '<br>';

// функция чтения странички
function CurlPage ( $path ) {
    // $path - страничка, какую смотрим
		
global $agent, $header, $referer, $arr_cookie, $cookie_file;

    // вызываем сеанс Curl
$ch = curl_init ( $path );
    // CURL будет возвращать результат, а не выводить его в печать
@curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , 1 );
    // выводим подробные сообщения о всех действиях
@curl_setopt ( $ch , CURLOPT_VERBOSE , 1 ); 
    // считываем страничку с хедером от сервера
@curl_setopt ( $ch , CURLOPT_HEADER , 0 );
    // отправим серверу user_agent сформированный нами самими
@curl_setopt ( $ch , CURLOPT_USERAGENT , $agent );
    // оправляем $referer, что пришли с первой страницы сайта
@curl_setopt ( $ch , CURLOPT_REFERER , $referer );
    // оправляем на сервер хедер, который мы сами сформировали
@curl_setopt ( $ch , CURLOPT_HTTPHEADER , $header );
    // при получении HTTP заголовка "Location: " будет 
    // происходить перенаправление
@curl_setopt ( $ch , CURLOPT_FOLLOWLOCATION , 1 );
    // запретить проверку сертификата удаленного сервера
@curl_setopt ( $ch , CURLOPT_SSL_VERIFYPEER, 0 );
    // не будем проверять существование имени
@curl_setopt ( $ch , CURLOPT_SSL_VERIFYHOST, 0 );
    // если есть массив с cookie, то отправим серверу, эти cookie
if ( @is_array ($arr_cookie)){
      while (list($key, $val) = @each ($arr_cookie)){
      $COKKIES .= trim ($val[0])."=". trim ($val[1])."; ";
       }
@curl_setopt ( $ch , CURLOPT_COOKIE , $COKKIES." expires=Mon, 14-Apr-08 10:34:13 GMT" );
}
    // если с сервера пришло cookie, то запишем его в файл $cookie_file
@curl_setopt ( $ch , CURLOPT_COOKIEJAR , $cookie_file );
@curl_setopt ( $ch , CURLOPT_COOKIEFILE , $cookie_file );
    // если мы послали данные из формы, которая стоит 
    // на страничке $path, добавляем метод $_POST
if (isset($_POST) and $_SERVER["REQUEST_METHOD"]=="POST"){
     @curl_setopt ( $ch , CURLOPT_POST , 1 );
     @curl_setopt ( $ch , CURLOPT_POSTFIELDS , substr ( data_encodes ( $_POST ), 0 , - 1 ) );
} 
    // получаем страничку $path с хедером
$tmp = @curl_exec ( $ch );
    // закрываем сеанс Curl
curl_close ( $ch ); 

    // если Curl ничего не вывел пробуем это сделать output_r();
    // эта функция описана здесь, она использует сокет.
if ($tmp==''){ $tmp = output_r ($path); }
return $tmp;
}

?>

Ссылки по теме Регулярные выражения, Часть I

Настройки просмотра комментариев

Выберите нужный метод показа комментариев и нажмите "Сохранить установки".

Спасибо, своевременно.

Спасибо, своевременно.

Комментировать

Содержание этого поля является приватным и не предназначено к показу.