Javenue logo

Javenue

Программирование на Java

Информационные технологии

Генерация sitemap.xml и нюансы использования Google Sitemap

Sitemap позволяет владельцам сайтов и веб-мастерам сообщить поисковым системам о структуре сайта и обновлении контента на его страницах. Таким образом при правильном использовании sitemap можно добиться лучшего индексирования страниц веб-ресурса поисковыми системами. Соответственно, при неправильном использовании данной технологии можно навредить самому себе (точнее своему интернет детищу).

В этой статье я хочу коротко рассказать вам о Google Sitemap, предоставить программный код на Java для простой генерации sitemap.xml, ну и открыть некоторые нюансы обнаруженные моим другом и мной, и о которых, как мне кажется, многие не знают.

Sitemap состоит из набора блоков, каждый из которых описывает одну страницу сайта и предоставляет некоторую информацию о динамике ее обновления. Вот небольшой пример sitemap.xml, сгенерированный с помощью программы на java, которую я предоставлю ниже:

<?xml version='1.0' encoding='UTF-8'?>
<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>
  <url>
    <loc>http://www.javenue.info/post/20</loc>
    <changefreq>weekly</changefreq>
    <priority>0.5</priority>
    <lastmod>2009-02-20T15:32:20+02:00</lastmod>
  </url>
  <url>
    <loc>http://www.javenue.info/post/73</loc>
    <changefreq>daily</changefreq>
    <priority>0.3</priority>
  </url>
  <url>
    <loc>http://www.javenue.info/post/2</loc>
    <changefreq>weekly</changefreq>
    <priority>0.5</priority>
  </url>
</urlset>

Расскажу о каждом элементе входящем в блок url:

1. loc - собственно URL страницы

2. changefreq - как часто данная страница может изменяться. Возможные значения - always, hourly, daily, weekly, monthly, yearly, never. Судя по всему, данный параметр еще используется поисковиками, для того чтобы вычислить приблизительную дату следующего захода на страницу.

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

4. lastmod - время последнего обновления конетнта страницы. Для сайтов со статическим контентом можно не использовать lastmod, changfreq будет более чем достаточно.

Ну а вот ужасная вещь: практически во всех статьях, которые я читал о google sitemap и о генерации сайтмеп, есть очень подозрительная вещь:

<lastmod>2009-02-20</lastmod>

Здесь не указано время обновления страницы. Google конечно понимает разные форматы дат, но давайте рассмотрим такой случай:

1. вы обновили страничку, например 2009-02-20.

2. crawler заходит на сайт, скачиавет страничку. Скорее всего он помечает, что заходил на эту страницу 2009-02-20.

3. В этот же день вы находите ужасные недочеты в контенте страницы и полностью переделываете ее. После изменений дата lastmod все равно остается 2009-02-20.

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

Так что настоятельно вам рекомендую использовать формат с датой, временем и time зоной.

Ну а вот и обещаный программный код для генерации sitemap:

public class GoogleSitemap {
    private String publicUrl;
    private List<Url> urls = new ArrayList<Url>();

    public String getPublicUrl() { return publicUrl; }
    public void setPublicUrl(String publicUrl) { this.publicUrl = publicUrl; }

    public List<Url> getUrls() { return new ArrayList<Url>(urls); }
    public Url addUrl(Url url) { urls.add(url); return url; }
    public void removeUrl(Url url) { urls.remove(url); }

    private String w3cDateTime(Date date) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
        String formated = df.format(date);
        return formated.substring(0, 22) + ":" + formated.substring(22);
    }

    public void write(Writer writer) {
        PrintWriter xml = new PrintWriter(writer);
        xml.println("<?xml version='1.0' encoding='UTF-8'?>");
        xml.println("<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>");

        for (Url url : urls) {
            xml.println("<url>");
            xml.println("<loc>" + (publicUrl == null ? "" : publicUrl) + url.loc + "</loc>");
            xml.println("<changefreq>" + url.changefreq.name().toLowerCase() + "</changefreq>");
            xml.println("<priority>" + url.priority + "</priority>");
            if (url.lastModified != null)
                xml.println("<lastmod>" + w3cDateTime(url.lastModified) + "</lastmod>");
            xml.println("</url>");
        }

        xml.println("</urlset>");
        xml.flush();
    }

    public static class Url {
        private String loc;
        private float priority = 0.5f;
        private Changefreq changefreq = Changefreq.WEEKLY;
        private Date lastModified = null;

        public Url(String loc) {
            this.loc = loc;
        }

        public Url(String loc, Changefreq changefreq) {
            this.loc = loc;
            this.changefreq = changefreq;
        }

        public Url(String loc, Changefreq changefreq, float priority) {
            this.loc = loc;
            this.changefreq = changefreq;
            this.priority = priority;
        }

        public String getLoc() { return loc; }
        public void setLoc(String loc) { this.loc = loc; }

        public float getPriority() { return priority; }
        public void setPriority(float priority) { this.priority = priority; }

        public Changefreq getChangefreq() { return changefreq; }
        public void setChangefreq(Changefreq changefreq) { this.changefreq = changefreq; }

        public Date getLastModified() { return lastModified; }
        public void setLastModified(Date lastModified) { this.lastModified = lastModified; }
    }

    public static enum Changefreq {
        ALWAYS, HOURLY, DAILY, WEEKLY, MONTHLY, YEARLY, NEVER
    }

    public static void main(String[] args) throws IOException {
        GoogleSitemap sitemap = new GoogleSitemap();
        sitemap.setPublicUrl("http://www.javenue.info");
        Url url1 = new Url("/post/20");
        url1.setLastModified(new Date());
        sitemap.addUrl(url1);
        sitemap.addUrl(new Url("/post/73", Changefreq.DAILY, 0.3f));
        sitemap.addUrl(new Url("/post/2", Changefreq.WEEKLY));
        sitemap.write(new PrintWriter(System.out));
    }
}

Если вы спросите, что такое

formated.substring(0, 22) + ":" + formated.substring(22);

Так вот, это небольшой хак. Дело в том, что по стандарту w3c в таймзоне должно присутствовать двоеточие, а Z для таймзоны в SimpleDateFormat двоеточие не ставит.

Надеюсь, статья была вам интересна и информация из статьи когда-нибудь вам пригодится. Всего вам хорошего.



Комментариев: 4

  Выйти

  * для публикации комментариев нужно  

Konstantin Chapiuk:

По многочисленным просьбам посетителей скоро сделаю отдельную библиотеку для работы с robots.txt, sitemap.xml и RSS.

Ilia Dmitriev:

исправь количетсов

Руслан Тимченко:

Не могу скачать

Руслан Тимченко:

как скачать и подходите на мой Android?