Sitemap.xml или «Делать было нечего...»

    Новогодние праздники 666+666+666+6+6+6-го года в самом разгаре. За серьезные вещи совсем не хочется браться. Зато можно заняться всякими мелочами, до которых обычно не доходят руки. Такой мелочью для меня стала генерация файлов Sitemap.xml.
    Sitemap.xml — это файл, содержащий в специальном формате ссылки на страницы сайта, которые должны быть проиндексированы поисковыми системами. Исчерпывающая информация о формате может быть найдена на Sitemaps.org.
    Давно хотелось иметь удобный инструмент для формирования данных файлов.

    Генерация Sitemap.xml

    Поиски в сети дали множество «удобных online-сервисов» для ручного создания карты сайта и несколько простеньких скриптов, которые также непригодны для создания карты сайта с большим количеством ссылок.

    Что хотим?..


    Чтобы сгенерировать sitemap.xml для небольшого сайта не нужно много усилий. Для больших же ресурсов есть особенности.
    Существуют ограничения на размер файлов sitemap.xml в 10Мб, а также ограничения на в 50000 ссылок на один файл. Автоматическая обработка данных ограничений и стала моей целью.
    Таким образом, были сформированы следующие требования:
    1. Скрипт должен следить за размером получаемых файлов и количеством добавленных url. При необходимости, создавать несколько файлов в соответствии с форматом;
    2. Не хранить промежуточные данные в памяти;
    3. Создавать по необходимости сжатые версии файлов, для отдачи с помощью nginx;
    4. Автоматически выполнять простейшие проверки данных.

    Сказано — сделано. Конечный вариант скриптов можно найти по ссылке в конце статьи.

    Чего не делает скрипт?


    Чтобы предупредить дальнейшие вопросы скажу, что скрипт не является универсальным решением, которое в один чих сгенерирует карту для произвольного сайта.
    Это лишь инструмент, и список ссылок, которые будут добавляться в файл, необходимо формировать самостоятельно, возможно, в несколько заходов.
    Кроме того, скрипт не исправляет и не кодирует url, переданные ему. Поэтому позаботиться о соответствии ссылок стандарту RFC-3986 для URI, стандарту RFC-3987 для IRI и XML-стандарту.

    Пример


    С помощью данного инструмента карту сайта можно создавать примерно так:
    Пример скрипта, генерирующего карту сайта
    <?php
    require_once(dirname(__FILE__)."/../common.inc.php");
    set_time_limit(0);
    ini_set('memory_limit', '128M');
    
    $dir = dirname(__FILE__);//document root path
    $tmp_dir = dirname(__FILE__);//temp path
    $base_url = 'http://mysite.ru/';//url with sitemaps (http://mysite.ru/sitemap.xml)
    $gzip = true;
    $config = array('path' => $dir , 'tmp_dir'=>$tmp_dir,'base_url'=>$base_url,'gzip'=>$gzip, 'gzip_level'=>9);
    
    $builder = new SitemapBuilder($config);
    
    $time = time();
        
    $builder->start();
    $builder->addUrl($base_url,$time,1.0);
    $builder->addUrl($base_url."news",$time,1.0);
    
    /*
    //this is example adding url 
    $documents = News::find(array('criteria'=>'is_published=1'));
    foreach($documents as $document)
      $builder->addUrl($document->getUrl(),$document->getUtime(),0.8);
    */    
    $builder->commit();
    



    Ссылки


    1. Sitemaps.org
    2. Исходники скриптов генерации Sitemap.xml
    3. Репозиторий на github.com
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 29

      +3
      Я просто оставлю это здесь:
        –4
        Ни чего не имею против всякого рода новомодных приблуд… Но это не значит, что все должны ими пользоваться.
        Особенно не люблю, когда мне пытаются навязывать, что и куда положить, как программировать и т.п. Предпочитаю знать, что включаю в проект, и как оно рабатает.
          0
          Ни чего не имею против всякого рода новомодных приблуд

          Это не новомодные приблуды, а вещи которые должен хотя бы знать уважающий себя php-программист
            –1
            Вы считаете, что компосер должны использовать все? Это именно та вещь, которую просто необходимо использовать каждому php-программисту?
              –1
              Всё идёт к тому…
                –1
                Я считаю, что нужно использовать в каждом php-проекте, где нужна хотя бы одна зависимость или это библиотека. Он решает проблему версионирования, подключения классов и даже поиска нужного пакета
              +4
              Я тоже предпочитаю знать, что я включаю в проект и как оно работает. Поэтому я буду подключать всё через composer, и пользоваться общепринятыми стандартами или библиотеками, которые этот стандарт поддерживают.
              • PSR-2 помогает сделать код более читабельным, а так же другим людям позволяет сразу же понят, как правильно писать (табы, пробелы, фигурные скобки, прочее)
              • PSR-4 помогает сделать структуру, в которой не нужно использовать в каждом файле include.
              • Composer помогает подключать библиотеки стандартно с помощью одной команды, и больше не думать как подключать каждую из библиотек
              • PHPUnit — признанный инструмент для написания unit-тестов. Я видел, что у вас тоже есть тесты, но они не стандартизированы, а значит ни одна система сборки их не сможет прогнать без доработки напильником.

              Единственное от чего можно отказаться это от GrumPHP, но он мне очень нравится, т.к. проверяет код перед комитом (на стандарты, запускает тесты и прочее)
                +1
                Да ладно, travis вполне сможет прогнать эти тесты.
                  0
                  Да, с тестами действительно неправ, т.к. это на самопис, а github.com/limb-php-framework/limb/tree/master/tests_runner
                    0
                    Да всё равно, самопис или нет. Ни один CI не завязан ни на одну конкретную систему тестирования.
                      0
                      Конечно. Но для многих есть плагины под популярные системы. А если это самопис — то придется самому писать и плагин для CI
                        –2
                        да вы правы Limb. Скажу больше test_runner это обвертка для PHPUnit.
              +2
              Я тоже писал библиотеку для генерации SiteMap: github.com/samdark/sitemap. Её отличительная особенность в том, что она не кушает память и отлично подходит для создания карт с сотнями тысяч URL. У вас же библиотека для этого не годится. Прожорливая.
                –1
                Вы видимо мой код посмотрели… Подскажите, где кушает память. Вы то вот написали код, который сгенерирует файлы sitemap.xml, которые не будут приняты поисковыми системами (часто сайтмапы не добираются до ограничения в 50000 ссылок, 10Мб достигается раньше).
                  0
                  Я точно посмотрел, скажу прямо, это полный отстой.
                    –1
                    Если я говорю, что у вас ошибка, то указываю в чем. А так и я могу вашу реализацию какашкой обозвать.
                      –1
                      У меня тоже хватает отстойного кода, но он мой, для меня. А указания есть в 1 посте, просто там не написано говнокод.
                    0
                    Больше всего при сжатии. Ну и немного на буферизацию строки, которую будем писать.

                    Проверку лимита в 10 мегабайт добавлю. Упустил это дело.
                  –2
                  Вот у меня вопрос. А что такого вы можете своим скриптом сгенерировать чего поисковик (который ещё и JS исполняет) не найдет сам?
                  Если ничего — то какой в этом вообще смысл?
                    0
                    Рассказать поисковику о всех страницах сайта, а не только о тех, которые он знает.
                      –1
                      О каких страницах он может не знать? У него 200% более продвинутый парсер, который (как я уже говорил) поддерживает даже исполнение JS и находит ссылки в динамическом содержимом.
                          0
                          А автоматически определить, когда еще заходить на конкретные страницы сайта поисковик сможет? А без дополнительной нагрузки на сам сайт?
                            0
                            Вы, наверное, не поверите — но да. Он определяет частоту изменения содержимого страницы и подстраивает обход сайта. Именно поэтому изменение на малопосещаемом сайте может быть незамеченным несколько дней, а статья из популярного сайта новостей появляется в выдаче мгновенно.
                              0
                              Ага… Вот только чтобы подобрать «частоту изменения», ему приходится заходить на страницу довольно часто в начале… Именно про это я говорил, когда упомянул «дополнительную нагрузку на сайт». А если потом контент на странице начнет меняться часто — робот это либо будет игнорировать (говорю по опыту), либо долго подстраиваться (в теории), что снова создаст дополнительную нагрузку.

                              Далее: может ли робот проиндексировать страницу, на которую нет ни одной ссылки. Ни статической, ни динамической. Поисковики, конечно, умные, но не настолько…

                              Представьте, что у вас часть сайта на отдельном поддомене. Для поискового робота — это совсем отдельный проект. Указав ему страницы через sitemap.xml — вы указываете связь между основным доменом и поддоменом. Таких сценариев достаточно много, на самом деле. Вот только вам они не интересны и не нужны, иначе вы бы про них знали).

                              Ну и напоследок: если сами поисковики просят создавать sitemap — считаете, они глупые?
                                0
                                Вот только чтобы подобрать «частоту изменения»

                                Ну погодите, разговор начался из статьи, вы видите в ней поддержку данной функциональности? Я же не говорю что у вас может быть сайт новостей, где вы на основе данных из БД о создании и изменении записей генерируете sitemap.xml. Речь о генераторе описанном в статье, который прикидается очень простым поисковиком.
                                Далее: может ли робот проиндексировать страницу, на которую нет ни одной ссылки. Ни статической, ни динамической. Поисковики, конечно, умные, но не настолько…

                                Зачем поисковику (пользователю поисковика) ссылка на страницу, на которую пользователь сам никак попасть не может?
                                Представьте, что у вас часть сайта на отдельном поддомене.

                                Это дико странный сайт и сомневаюсь что sitemap.xml вам с этим поможет. Зеркала указываются через robots.txt, а вот часть сайта на отдельном домене — это другой сайт, всё верно. И поисковики не рекомендуют, если мне не изменяет память, к примеру, языковые версии, разносить по разным доменам по той же причине.
                                Ну и напоследок: если сами поисковики просят создавать sitemap — считаете, они глупые?

                                Нет, это было вполне резонно когда поисковики были маленькие и им было сложно переваривать большие сайты, тогда зная свой сайт вы могли (в теории) пропарсить его более качественно и сгенерировать sitemap.xml. Сейчас такой проблемы нет, а вы очень маловероятно напишете лучший парсер.

                                Хорошо структурированные данные, как то новости, вполне имеет смысл засовывать в sitemap.xml ввиду простоты и качества (точное время создания/изменения) реализации. Вручную проходить по сайту самописным парсером и засовывать это в sitemap.xml смысла не вижу.
                                  0
                                  >Ну погодите, разговор начался из статьи, вы видите в ней поддержку данной функциональности?

                                  Вообще — да: https://github.com/vasiatka/sitemap/blob/master/sitemap/src/SitemapBuilder.class.php#L56. Это стандарт.

                                  >Зачем поисковику (пользователю поисковика) ссылка на страницу, на которую пользователь сам никак попасть не может?

                                  С чего вы решили, что на страницу нельзя попасть?))) Я говорил только про отсутствие ссылок.

                                  >Это дико странный сайт и сомневаюсь что sitemap.xml вам с этим поможет.

                                  Ой-ли… С чего вдруг он стал странным? С того, что тематическую часть вынесли в отдельный поддомен? И да, sitemap с этим поможет.

                                  >Зеркала указываются через robots.txt, а вот часть сайта на отдельном домене — это другой сайт, всё верно.

                                  Т.е., m.habrahabr.ru — это отдельный сайт? Ну а news.yandex.ru конечно-же не имеет никакого отношения к yandex.ru). Более простой пример — news.nnm.me — на поддоменах отдельные разделы, но никак не отдельные сайты.

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

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

                                  >Сейчас такой проблемы нет, а вы очень маловероятно напишете лучший парсер.

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

                                  >Вручную проходить по сайту самописным парсером и засовывать это в sitemap.xml смысла не вижу.

                                  Вы уверены, что комментируете тот пост, который хотите? Как-бы сам пост, пример в посте и ссылка на гитхаб говорят только о генерации sitemap для своего сайта, ни о каком ручном проходе стороннего сайта речи нет)
                                    0
                                    Вообще — да: github.com/vasiatka/sitemap/blob/master/sitemap/src/SitemapBuilder.class.php#L56. Это стандарт.

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

                                    С того что ссылка — это основной способ перехода между страницами сайта. Если это не ссылка — весьма небольшая вероятность что туда нужно соваться поисковику. Я понимаю, что можно сгенерировать ссылку с помощью JS и бросить туда пользователя, но это в подавляющем большинстве не то, куда поисковик должен заглядывать.
                                    Ой-ли… С чего вдруг он стал странным? С того, что тематическую часть вынесли в отдельный поддомен? И да, sitemap с этим поможет.

                                    С того что вы почему-то вынесли его не на domain.tld/news, а на news.domain.tld. Я понимаю, что можно сначала создать себе проблему, а потом пытаться её решить, но это не слишком продуктивное времяпровождение. Вы поищите что люди пишут по поводу поддоменов — поддомен это отдельный сайт для отдельного региона, отдельного продукта компании и так далее.
                                    Т.е., m.habrahabr.ru — это отдельный сайт?

                                    Загляните на habrahabr.ru/sitemap.xml и потом на m.habrahabr.ru/sitemap.xml
                                    Ну а news.yandex.ru конечно-же не имеет никакого отношения к yandex.ru).

                                    Кроме того что владелец сайта одна компания — никакого. На одном поиск, а на другом новости. Их обслуживают разные сервера, над ними работают разные команды и даже дизайн отличается, хоть и в стиле компании. То есть сама компания — почти единственное что объединяет сайты, потому и поддомен.
                                    Более простой пример — news.nnm.me — на поддоменах отдельные разделы, но никак не отдельные сайты.

                                    Это как раз более сложный вариант, тот, который я называл выше странным. Это по сути отображение новостей из определённого раздела, это и правда часть основного сайта, и если бы разработчики вынесли его в nnm.me/news — то подняли бы основной сайт в выдаче.
                                    Расширение для поддержки поддоменов чисто гугловская штука судя по тому что пишут люди: https://productforums.google.com/forum/#!topic/webmasters/3cB5qpGv-zk
                                    Цитата из спецификации:
                                    Note: A Sitemap index file can only specify Sitemaps that are found on the same site as the Sitemap index file. For example, www.yoursite.com/sitemap_index.xml can include Sitemaps on www.yoursite.com but not on www.example.com or yourhost.yoursite.com. As with Sitemaps, your Sitemap index file must be UTF-8 encoded.

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

                                    Парсер при том что статья о парсере. Если у вас sitemap.xml генерируется на основании точных данных из БД — вопросов нет.
                                      0
                                      >Это я видел, и это полумера. Такую цифру спокойно выведет поисковик, а фиксированную статью повторно индексировать смысла нет, то есть параметр очень неточный.

                                      Да куда уж точнее-то? Мы же сами указываем, раз в какой период заходить на страницу…

                                      >Дату модификации скрипт не может проставить, поскольку у него нет нужной информации.

                                      Ах, вот оно что… Есть. Подробнее — в самом конце моего комментария.

                                      >С того что вы почему-то вынесли его не на domain.tld/news, а на news.domain.tld.

                                      А почему я должен делать тематику частью урла, а не домена? По мне, news.domain.tld/moscow куда приятнее и понятнее, чем domait.tld/news/moscow.

                                      >Вы поищите что люди пишут по поводу поддоменов — поддомен это отдельный сайт для отдельного региона, отдельного продукта компании и так далее.

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

                                      >и если бы разработчики вынесли его в nnm.me/news — то подняли бы основной сайт в выдаче.

                                      Откуда такая информация? Мне правда интересно. Тем более, что сами посты не находятся в поддоменах, в них только списки постов.

                                      >Цитата из спецификации

                                      говорит об индексном файле, т.е. ссылки на части sitemap должны располагаться в пределах одного домена. В спецификации нет ни слова о том, что страницы должны располагаться в пределах домена.

                                      >Парсер при том что статья о парсере.

                                      Я уж было усомнился в своей читательской способности, но нет… Перечитал пост, поискал через Cmd+F — нет в посте ни слова про парсер. Откуда вы это взяли?

                                      Я понял, что мы говорим абсолютно о разных скриптах. Тот, что в посте, генерирует на основе данных, переданных ему. В нем нет паука, нет парсера и пр. (сужу по примеру, а не коду). И пример говорит мне о том, что sitemap генерируется по данным на основе БД:

                                      $documents = News::find(array('criteria'=>'is_published=1'));
                                      foreach($documents as $document)
                                      $builder->addUrl($document->getUrl(),$document->getUtime(),0.8);

                    Only users with full accounts can post comments. Log in, please.