Если 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+ (.{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 виде это будет
<<span class="start-tag">strong</span><span class="attribute-name"> class</span>=<span class="attribute-value">"b-head-logo__text"</span>> Нашлось<<span class="start-tag">br</span>>188&<span class="entity">nbsp;</span>ответов </<span class="end-tag">strong</span>>
Это и есть наша искомая строка.
Однако, не всё так просто. Варианты ответов Яши могут быть такими:
Нашлось
291 ответ
или
392 ответа
или
17 тыс. ответов
или
1 млн ответов
Как видим, нам необходимо выделить не только цифры, а цифры вместе со следующим словом тыс. или млн.
Для начала найдем то, от чего будем отталкиваться при поиске "искомой строки".
<strong class="b-head-logo__text"> - уникальный ключ во всем тексте, он и будет обозначать начало нашей искомой строки. То есть, сначала мы находим в тексте этот ключ, а затем начинаем выделять следующие за ним цифры и слова.
Cоставляем строку для REGEXP таким образом, чтобы он полностью совпал с искомой строкой. Думаю, она должна быть такой:
<strong class="b-head-logo__text">[^<]*<br>(\d+ (.{3}\.)*(.{3}\s)*)
где
- <strong class="b-head-logo__text"> - непосредственный набор литералов, совпадающий с началом искомой строки;
- [^<]* - любое количество (включая их отсутсвие) любых литерало, кроме левой угловой скобки "<". Совпадет со словом Нашлось и любым другим словом, которое Яша может тут вписать;
- <br> - набор литералов, непосредственно предшествующий цифрам (это для HTML они являются тэгом, а для нас - кучка значков-литералов) ;
- \d+ - цифры
- - набор симвлов после цифр
- (.{3}\.)* - три любых символа с точкой на конце (тыс.), либо их отсутствие
- (.{3}\s)* - три любых символа с пробелом на конце (млн), либо их отсутствие
- начиная с 4 пункта до конца берем в скобки, чтобы сохранить результат в переменной (получится, например, 17 тыс.)
Для отладки я использовал запущенный сервер 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; } ?>

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