Как выдать роботу Google страницы, которые он еще не видел?

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

Как проверить есть ли страница в индексе с помощью программирования?

Моя функция работала таким образом, что заходила в поиск, задавала запрос типа site:[ссылка], если ссылки такой не было, то у нас в поиске мы получаем ответ типа “По запросу site:[ссылка на сайт] ничего не найдено. ”.

Если ответ есть, то соответственно мы получаем ссылку. В теории это верный способ получить ответы, есть ли страница в индексе или нет, но на практике не все так просто.

После большого количества запросов из одного ip, гугл начинает выдавать капчу, то есть на нечеловеческие действия он требует человеческое подтверждение.

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

Коль мы получаем капчу, то еще и антикапчу можно подключить.

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

Если кому нужен будет скрипт, который просто заходит в поиск и чекает, пишите в комментариях, я выставлю.

Прокси уже сами прикрутите, я эту штуку не делал.

Альтернативный метод выдачи страниц для робота?

В общем мы решили сделать все значительно иначе, изначально цель была в том, чтобы робот побывал на странице и по возможности проиндексировал ее.

Методом проб и ошибок мы понимаем, что если боту не нравится страница, то он как не проси, не возьмет ее в индекс.

Для того, чтобы это случилось, нужно улучшать страницу, посмотреть где и что нужно убрать или добавить. В общем красиво поработать над страницей и тогда может быть что-то случится.

Но так как сайт очень большой, около 250 тысяч страниц, то тут в первую очередь важно чтобы он побывал на всех страницах, если побывает то там уже решится дальнейшая ее судьба, а мы уже ручками определим, как получилось и пойдем исправлять недостатки.

Что делать для того чтобы робот побывал на странице?

Подсунуть эту страницу под нос — это самый простой способ, но как это делать, когда страниц огромное количество?

Мы немного пообщались с целой командой, так как над сайтом работает несколько людей, и придумали такую штуку. 

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

Почему бы не написать скрипт, который определит где бывал робот — получить данные, где и когда, а после уже из базы вычесть те страницы где он еще не был, и запустить его туда.


К примеру сделать сквозной блок на сайте, под названием “новое на сайте”, а после выдавать ссылки которые робот еще не видел по нашему мнению.

Какие функции для этого потребовались? 

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

Далее мне нужно было определить когда заходил гугловский робот на сайт и куда. А после все полученные данные обработать и вывести результат. 

Сразу скажу что сайт написан на Laravel, потому попытаюсь давать два ответа для Laravel и на простой php сайт.

Вывод получается такой:

  1. Нужны три действия:
    1. Сбор базы имеющихся ссылок;
    2. Статистика где бывал робот и на каких страницах;
    3. Сравнение двух таблиц и реализация динамического блока ссылок;
  2. Понятно, что помимо указанного, писался сервис в админ панель, который позволял получать статистику где и как побывал бот и так дальше.
  3. Кроме того все это должно работать более менее быстро, а то если из-за этого страница будет грузиться дольше, то весь труд насмарку.

Собираем статистику по страницам и ботам

Для этого я написал две функции, которые будут работать на каждой странице нашего проекта. 

Обе функции будут работать будто администратор сидящий на ресепшене, проверять кто зашел и записывать где побывал, а толстосумов даже выделять особенной пометкой. Как-то так.

Выискиваем ботов:

public function isBot()
    {
        if (!empty($_SERVER['HTTP_USER_AGENT'])) {
            $options = array(
                'Googlebot', 'Googlebot-Image', 'Mediapartners-Google', 'AdsBot-Google',
                'bingbot', 'Accoona', 'ia_archiver', 'Ask Jeeves',
                'OmniExplorer_Bot', 'W3C_Validator', 'WebAlta', 'YahooFeedSeeker', 'Yahoo!',
            ); // в моем случае я ищу только пауков гугл, но я добавил несколько дополнительных, так же можно и роботов яндекса искать

            foreach($options as $row) {
                if (stripos($_SERVER['HTTP_USER_AGENT'], $row) !== false) { // если тот кото зашел имеется в нашем списке, тогда заносим его в нашу базу
                    $app_id = DB::table('applications')->where('app_name',HelpersController::getEnvApp())->first()->id; // это я так определяю на каком из проектов побывал робот, чтобы понимать его местонахождения

                    DB::table('bot_analitica')->insert(
                        [
                            'user_agent' => $_SERVER['HTTP_USER_AGENT'], // юзер агент, по нему можно понять из мобильного или десктопного писка пришел бот
                            'url' => url()->current(), // текущий юрл
                            'date' => date('Y-m-d H:i:s'), // дата и время когда был
                            'bot' => $row, // чтобы легче было фильтрировать
                            'app_id' => $app_id, // если у тебя не сетка сайтов, то строка лишняя
                        ]
                    ); // добавляем в базу
                }
            }
        }
    }

Получается, ботов мы уже можем вычислить, а функцию уже выводим где-нибудь в футере, хотя это уже не сильно важно.

А вот так я определю все ссылки которые мы имеем, причем роботы поисковых систем, ahrefs, semrush и другие сканеры помогут нам заполнить базу с минимальной нагрузкой и за несколько дней.

public function writeLinkOnBase($type) {
        $application = DB::table('applications')->where('app_name',HelpersController::getEnvApp())->first()->id; // тоже самое что и в предыдущий функции, если у тебя не сетка сайтов, то строчка точно лишняя
        $check = DB::table('link_base')->where('url', 'LIKE', url()->current())->first(); // ищем есть ли такая страница в базе
        if($check === NULL) { // если нет, то можно и схоранить ее в базе
            if(http_response_code() === 200) { // мне нужны только живые страницы, потому отсеиваем лишнее
                DB::table('link_base')->insert(
                    [
                        'url' => url()->current(),//  текущая ссылка.
                        'status' => 200, 
                        'in_google_index' => false, // лишняя строка, но возможно я когда-то начну определять есть ли страница в поиске
                        'app_id' => $application,
                        'page_type' => $type // важно если мы хотим выдавать определенный раздел
                    ]
                ); // сохраняем в базу
            }
        }
        if($check->app_id === 0) {
            DB::table('link_base')->where('id', $check->id)->update(['app_id' => $application,'page_type' => $type]); // я не сразу догалался что нужно еще и приложение с типом страниц записать, чтобы фильтр получился более качественный
        }
    }

В общем эти две функции позволили мне собирать довольно таки полезную информацию, наш SEO почему-то был в восторге от полученной информации, не понимаю почему, возможно кто-то может мне сказать?

И все же когда была уже сформирована какая-то база, я продолжил свою работу.

Выводим блок с неизвестным для ссылками на страницу

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

public function getLinksList() {
        $app_id = HelpersController::getAppId(); // получаю id из приложения на котором буду выводить блок
        $getList = DB::table('link_base')
            ->where([
            ['app_id', $app_id],
            ['page_type','executors']
        ])->whereNotIn('url', [DB::raw("SELECT url FROM bot_analitica where app_id = $app_id and  DATE_FORMAT(date, '%Y-%m') >= DATE_FORMAT(( CURDATE() - INTERVAL 3 MONTH ), '%Y-%m')")])->limit(100)->get()->shuffle(); // сравниваю два списка и получаю 100 записей из них, позже поясню зачем.
// Ларавел имеет свой генератор запросов, потому решил выставить отдельно сам Mysql запрос
// select * from `link_base` where (`app_id` = ? and `page_type` = ?) and `url` not in (SELECT url FROM bot_analitica where app_id = 15 and DATE_FORMAT(date, '%Y-%m') >= DATE_FORMAT(( CURDATE() - INTERVAL 3 MONTH ), '%Y-%m')) limit 100


        $listForCheck = []; // здесь будем хранить все ссылки для вывода на сайте
        $titleGenerator = DB::table('pages')->where([
            ['apps_to_display',$app_id],
            ['type','executors_page'],
        ])->first(); // здесь я получаю тайтл для того чтобы сформировать анкор ссылки
        $count = 0;
        foreach ($getList as $list) {
            $link = array_reverse(explode('/',$list->url)); //получаю слаги ссылок

            if(preg_match('/city-.*/',$link[0]) || preg_match('/kerulet-.*/',$link[0])) { // так как у меня есть города и районы, то нужно так же и их поределить
               
 $arr = array(
                    'city-' => '',
                    'kerulet-' => '',
                ); //ищем города и районы в слагах

                foreach ($arr as $key => $value) {
                    $link[0] = str_replace($key,$value,$link[0]); // убираем их, чтобы просто получить название города либо района
                }

                $city = DB::table('cities')->where('slug',$link[0])->first()->name; // получаем название города из базы
                $cat = DB::table('loc_categories')->where('slug',$link[1])->first()->title; // получаем тайтл по нужной нам страницы из базы (в моем случае это категории)

            } else {
                $city = trans('main.MAIN_CITY_NOGRAMMAR'); // если города нет, то выводим стандартный 
                $cat = DB::table('loc_categories')->where('slug',$link[0])->first()->title; // тут практически тоже самое что и выше на 3 строчки
            }

            $arr = array(
                '{{city}}' => $city,
                '{{category}}' => $cat,
            );
            $title = $titleGenerator->seo_title;
            foreach ($arr as $key => $value) {
                $title = str_replace($key,$value,$title); // для генерации заголовков я использую в них переменные, а после заменяю на свои, все это можно и не делать, все зависит от особенности базы
            }

            $listForCheck[] = array('title'=>$title,'url'=>$list->url); // Добавляю все полученное в одну переменную 

            $count++; 
            if ($count == 20){ // да мы выняли 100 ссылок, но на сайте нам потребуется всего 20, можно поменять на 10, тогда выдастся 10. Все для того, чтобы рандомно выдать 20 ссылок. Если использовать в Mysql запросе order by RAND(), по страница грузилась 10 секунд, что в 10 раз дольше обычного, а значит не вариант.
                break;
            }
        }

        return $listForCheck; 
    }

Ну и на этом мы дошли до завершительного этапа. Три функции для небольшого эксперимента, что из этого выйдет — это мы еще изучим, но думаю я не один кому потребовалась такая штука.

Цель была не дать готовый код, а показать как это работает у нас, а ты уже можешь написать свой велосипед, либо переписать под свои нужды, но если есть вопросы или помощь, ты знаешь где меня искать! (либо комменты, либо раздел обратной связи)

Несколько дополнительных слов по выдаче для роботов

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

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

Оставьте комментарий