Feedfetcher существует с 2009 года и по сей день остаётся ключевым механизмом доставки контента из RSS/Atom-фидов в экосистему Google. Понимание его работы важно для новостных изданий, блогеров, подкастеров и всех, кто использует фиды как канал распространения контента.
1. Что такое Feedfetcher-Google
1.1 User-Agent строка
# Основная строка:
FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)
# Расширенная строка с идентификатором фида:
FeedFetcher-Google; (+http://www.google.com/feedfetcher.html);
feedid=XXXXXXXXXXXXXXXXXX
# Также может встречаться:
Feedfetcher-Google (+http://www.google.com/feedfetcher.html)
Обратите внимание: User-Agent может содержать уникальный feedid — идентификатор конкретного фида. Это позволяет понять, какой именно фид запрашивается, если на сайте их несколько.
1.2 Google-сервисы, использующие Feedfetcher
| Сервис / Технология | Назначение | Тип использования фидов |
|---|---|---|
| Google News | Новостной агрегатор | RSS/Atom новостных изданий |
| PubSubHubbub (WebSub) | Протокол push-уведомлений об обновлениях | Подписка хаба на фиды издателей |
| Google Publisher Center | Управление присутствием в Google News | Фиды публикаций для Google News |
| Google Podcasts (историческое) | Подкаст-агрегатор (закрыт в 2024) | RSS-фиды подкастов |
| Google Play Newsstand (историческое) | Новостной агрегатор (преобразован в Google News) | RSS/Atom изданий |
1.3 Место в экосистеме Google-агентов
| Агент | Тип | Что получает | Уважает robots.txt? |
|---|---|---|---|
| Googlebot | Автономный краулер | HTML-страницы для индексации | ✔ Да |
| Googlebot-News | Автономный краулер | Новостные HTML-страницы | ✔ Да |
| Feedfetcher-Google | User-triggered fetcher | RSS / Atom фиды | ✖ Нет (см. раздел 7) |
| Google-Read-Aloud | User-triggered fetcher | HTML-страницы для TTS | ⚠ Частично |
| APIs-Google | Технический fetcher | Sitemap, robots.txt, API | Только явный UA |
1.4 Ключевые особенности
- Не индексирует контент для поиска — фиды не попадают в органическую выдачу (исключение: подкасты)
- Действует как агент пользователя — запрос всегда инициирован реальным человеком
- Консолидирует запросы — делает один fetch для всех подписчиков данного фида
- Распределённая система — работает с множества машин, расположенных близко к серверам издателей
- Игнорирует robots.txt — как user-triggered fetcher, обходит эти директивы
1.5 IP-адреса
# Feedfetcher использует IP из списка user-triggered fetchers:
https://developers.google.com/static/search/apis/ipranges/user-triggered-fetchers-google.json
# Серверы часто располагаются в той же сети, что и сайт,
# для снижения latency и экономии bandwidth
2. Как работает Feedfetcher-Google
2.1 Принципиальное отличие от краулеров
| Характеристика | Googlebot (краулер) | Feedfetcher (fetcher) |
|---|---|---|
| Инициатор запроса | Алгоритм Google | Реальный пользователь или PubSubHubbub-хаб |
| Что обходит | HTML-страницы, открывая ссылки | Только конкретный URL фида — не следует по ссылкам |
| Цель | Индексация для поиска | Доставка контента фида подписчикам |
| Влияние на SEO | ✔ Прямое | ✖ Нет (кроме подкастов) |
| robots.txt | ✔ Уважает | ✖ Игнорирует |
| Частота | По расписанию Google | Обычно раз в час, зависит от обновлений |
| Консолидация | Нет | Один запрос = все подписчики данного фида |
2.2 Алгоритм работы
- Пользователь подписывается на RSS/Atom-фид через Google-сервис (например, добавляет источник в Google News).
- Google-сервис регистрирует фид в системе Feedfetcher.
- Feedfetcher делает первый fetch фида, чтобы получить текущий контент.
- Контент кешируется и доставляется всем подписчикам этого фида.
- Feedfetcher периодически обновляет фид — обычно не чаще одного раза в час.
- При использовании PubSubHubbub: издатель пингует хаб при публикации → хаб уведомляет Feedfetcher → немедленный fetch.
- Если фид не меняется — Feedfetcher может реже его запрашивать (адаптивная частота).
2.3 Консолидация запросов — экономия bandwidth
Одна из ключевых архитектурных особенностей Feedfetcher: если 10 000 пользователей подписались на один и тот же фид, Feedfetcher делает один запрос к серверу и раздаёт результат всем 10 000 подписчикам. Это принципиально отличается от ситуации, когда каждый RSS-reader делал бы запрос самостоятельно.
# Сравнение нагрузки:
# БЕЗ Feedfetcher (каждый клиент сам):
# 10 000 подписчиков × 1 запрос в час = 10 000 req/h к вашему серверу
# С Feedfetcher (консолидированно):
# 1 запрос в час к вашему серверу = данные для 10 000 подписчиков
# Экономия: 99.99% запросов
2.4 Что Feedfetcher анализирует в фиде
| Элемент фида | Как используется | Важность |
|---|---|---|
Записи (<item> / <entry>) |
Основной контент для доставки подписчикам | ⭐⭐⭐⭐⭐ Критически важно |
Заголовок (<title>) |
Отображается в интерфейсе Google News | ⭐⭐⭐⭐⭐ Критически важно |
Ссылка (<link>) |
URL оригинальной статьи | ⭐⭐⭐⭐⭐ Критически важно |
Дата (<pubDate> / <updated>) |
Определяет свежесть и порядок записей | ⭐⭐⭐⭐⭐ Критически важно |
Описание (<description>) |
Анонс / краткое содержание | ⭐⭐⭐⭐ Очень важно |
Полный текст (<content:encoded>) |
Полное содержание статьи | ⭐⭐⭐⭐ Очень важно |
GUID (<guid>) |
Уникальный ID записи — дедупликация | ⭐⭐⭐⭐ Очень важно |
Автор (<author>) |
Отображается в интерфейсе | ⭐⭐⭐ Важно |
Категории (<category>) |
Тематическая классификация | ⭐⭐⭐ Важно |
Изображение (<media:thumbnail>) |
Превью в Google News | ⭐⭐⭐⭐ Очень важно |
| Enclosure (для подкастов) | Ссылка на аудиофайл эпизода | ⭐⭐⭐⭐⭐ Для подкастов критически |
3. PubSubHubbub (WebSub) — мгновенные обновления
PubSubHubbub (сейчас официально называется WebSub — стандарт W3C) — протокол, позволяющий издателям мгновенно уведомлять Feedfetcher об обновлениях фида. Без этого протокола Feedfetcher проверяет фид по расписанию (раз в час и реже). С PubSubHubbub — немедленно при публикации.
3.1 Как работает PubSubHubbub
- Издатель указывает в фиде ссылку на PubSubHubbub-хаб (
<atom:link rel="hub">). - Google (как подписчик хаба) регистрируется для получения уведомлений об этом фиде.
- При публикации новой записи издатель пингует хаб.
- Хаб уведомляет всех подписчиков, включая Feedfetcher Google.
- Feedfetcher немедленно делает fetch обновлённого фида.
- Новый контент появляется в Google News в течение нескольких минут.
3.2 Настройка PubSubHubbub в фиде
<!-- RSS 2.0 с PubSubHubbub: -->
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:media="http://search.yahoo.com/mrss/">
<channel>
<title>Название издания</title>
<link>https://example.com</link>
<description>Описание фида</description>
<language>ru</language>
<lastBuildDate>Thu, 08 May 2026 14:30:00 +0300</lastBuildDate>
<!-- Self-link (обязательно): -->
<atom:link rel="self"
type="application/rss+xml"
href="https://example.com/feed.rss"/>
<!-- PubSubHubbub хаб Google: -->
<atom:link rel="hub"
href="https://pubsubhubbub.appspot.com/"/>
<item>
<title>Заголовок статьи</title>
<link>https://example.com/article/slug/</link>
<guid isPermaLink="true">https://example.com/article/slug/</guid>
<pubDate>Thu, 08 May 2026 14:30:00 +0300</pubDate>
<author>editor@example.com (Иван Иванов)</author>
<description>Краткое описание статьи для анонса</description>
<content:encoded><![CDATA[
<p>Полный HTML-текст статьи...</p>
]]></content:encoded>
<media:thumbnail url="https://example.com/images/article-thumb.jpg"
width="1200" height="630"/>
<category>Технологии</category>
</item>
</channel>
</rss>
3.3 Пинг PubSubHubbub хаба при публикации
# Ручной пинг Google PubSubHubbub хаба:
curl -X POST https://pubsubhubbub.appspot.com/ \
-d "hub.mode=publish" \
-d "hub.url=https://example.com/feed.rss"
# Ответ: HTTP 204 No Content (успех) или 400 Bad Request (ошибка)
# Пинг через Python:
import requests
hub_url = "https://pubsubhubbub.appspot.com/"
feed_url = "https://example.com/feed.rss"
response = requests.post(hub_url, data={
"hub.mode": "publish",
"hub.url": feed_url
})
print(f"Status: {response.status_code}")
# 204 = успех
# Пинг нескольких фидов одновременно:
curl -X POST https://pubsubhubbub.appspot.com/ \
-d "hub.mode=publish" \
-d "hub.url=https://example.com/feed.rss" \
-d "hub.url=https://example.com/news-sitemap.xml"
3.4 Atom фид с PubSubHubbub
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Название издания</title>
<id>https://example.com/feed.atom</id>
<link rel="alternate" type="text/html" href="https://example.com"/>
<!-- Self-link: -->
<link rel="self" type="application/atom+xml"
href="https://example.com/feed.atom"/>
<!-- PubSubHubbub хаб: -->
<link rel="hub" href="https://pubsubhubbub.appspot.com/"/>
<updated>2026-05-08T14:30:00+03:00</updated>
<author>
<name>Редакция</name>
<email>editor@example.com</email>
</author>
<entry>
<title>Заголовок статьи</title>
<id>https://example.com/article/slug/</id>
<link rel="alternate" href="https://example.com/article/slug/"/>
<published>2026-05-08T14:30:00+03:00</published>
<updated>2026-05-08T14:30:00+03:00</updated>
<author><name>Иван Иванов</name></author>
<summary type="html">Краткое описание статьи</summary>
<content type="html"><![CDATA[
<p>Полный текст статьи...</p>
]]></content>
</entry>
</feed>
4. Фиды подкастов — особый случай
Подкастные RSS-фиды занимают особое место в экосистеме Feedfetcher: в отличие от обычных новостных фидов, подкасты индексируются в Google Search. Это единственный тип контента из фидов, который попадает в органическую выдачу Google напрямую через Feedfetcher.
4.1 Структура RSS-фида подкаста
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0">
<channel>
<title>Название подкаста</title>
<link>https://example.com/podcast/</link>
<description>Описание подкаста (до 4000 символов)</description>
<language>ru</language>
<copyright>© 2026 Название</copyright>
<!-- Self-link: -->
<atom:link rel="self" type="application/rss+xml"
href="https://example.com/podcast/feed.rss"/>
<!-- Изображение подкаста (минимум 1400×1400px): -->
<itunes:image href="https://example.com/podcast/cover.jpg"/>
<!-- Категория iTunes: -->
<itunes:category text="Technology"/>
<itunes:explicit>false</itunes:explicit>
<itunes:author>Иван Иванов</itunes:author>
<itunes:owner>
<itunes:name>Иван Иванов</itunes:name>
<itunes:email>podcast@example.com</itunes:email>
</itunes:owner>
<!-- Эпизод: -->
<item>
<title>Эпизод 42: Тема эпизода</title>
<description>Подробное описание эпизода</description>
<link>https://example.com/podcast/episode-42/</link>
<guid isPermaLink="true">https://example.com/podcast/episode-42/</guid>
<pubDate>Thu, 08 May 2026 10:00:00 +0300</pubDate>
<itunes:author>Иван Иванов</itunes:author>
<itunes:duration>45:30</itunes:duration>
<itunes:explicit>false</itunes:explicit>
<itunes:episode>42</itunes:episode>
<itunes:season>2</itunes:season>
<itunes:episodeType>full</itunes:episodeType>
<!-- Аудиофайл (enclosure — обязателен для подкастов): -->
<enclosure url="https://example.com/podcast/episode-42.mp3"
length="108965678"
type="audio/mpeg"/>
</item>
</channel>
</rss>
4.2 Требования Google к подкастным фидам
| Требование | Детали |
|---|---|
| Enclosure обязателен | Прямая ссылка на аудиофайл (MP3, AAC, OGG, OPUS) |
| GUID уникален | Постоянный уникальный идентификатор каждого эпизода |
| Изображение подкаста | Минимум 1400×1400px, максимум 3000×3000px, JPEG или PNG |
| itunes:author | Имя автора/ведущего |
| itunes:explicit | true / false — обязателен |
| Доступность фида | Фид публичен, нет блокировок для Feedfetcher |
| Valid RSS 2.0 | Корректный XML без ошибок |
5. Нагрузка на сервер
Feedfetcher создаёт нагрузку, принципиально отличающуюся от нагрузки основного Googlebot. Благодаря консолидации запросов (один fetch для всех подписчиков), реальная нагрузка значительно ниже, чем можно было бы ожидать при большой аудитории.
5.1 Типичная частота и нагрузка
| Сценарий | Частота fetch | Нагрузка |
|---|---|---|
| Редко обновляемый фид (< 1 статьи в день) | Несколько раз в день | Минимальная |
| Стандартный новостной фид | Раз в час и чаще | Низкая |
| Активное издание (10+ статей в день) | Несколько раз в час | Низкая — средняя |
| С PubSubHubbub (push) | Сразу после публикации + плановые проверки | Управляемая |
| Большой агрегатор (тысячи записей) | Раз в час, тяжёлый файл | Зависит от размера фида |
5.2 Факторы, влияющие на нагрузку
- Размер фида — фид с полным текстом тысяч статей без пагинации весит значительно больше
- Количество подписанных Google-сервисов — каждый сервис может инициировать отдельные запросы
- Перезапуск серверов Feedfetcher — при редком рестарте серверов возможны повторные запросы уже обработанных фидов
- Сетевые задержки — могут создавать видимость более частых запросов в логах
- Несуществующие URL — если пользователь подписался на несуществующий URL, Feedfetcher будет регулярно проверять его
5.3 Оптимизация нагрузки
# Nginx — кеш и gzip для RSS/Atom фидов:
location ~* /feed\.(rss|xml|atom)$ {
# gzip сжатие обязательно:
gzip on;
gzip_types application/rss+xml application/atom+xml text/xml;
# Кеш: не слишком долгий — фид должен быть свежим:
add_header Cache-Control "public, max-age=300"; # 5 минут
add_header Vary "Accept-Encoding";
# ETag для условных запросов:
etag on;
}
# Поддержка условных запросов (If-Modified-Since, ETag):
# Feedfetcher поддерживает HTTP conditional requests.
# Если фид не изменился — отвечайте 304 Not Modified:
location /feed.rss {
etag on;
if_modified_since exact;
add_header Last-Modified $date_gmt;
}
6. Обнаружение в логах
6.1 Как выглядит запись
# Nginx access.log — стандартный запрос Feedfetcher:
66.249.85.10 - - [08/May/2026:20:15:33 +0000] \
"GET /feed.rss HTTP/1.1" \
200 84321 "-" \
"FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"
# Запрос с идентификатором фида:
66.249.85.11 - - [08/May/2026:20:15:34 +0000] \
"GET /feed.rss HTTP/1.1" \
200 84321 "-" \
"FeedFetcher-Google; (+http://www.google.com/feedfetcher.html); feedid=XXXXXXXXXXXXXXXX"
# Запрос к несуществующему фиду (пользователь ввёл неверный URL):
66.249.85.12 - - [08/May/2026:20:15:40 +0000] \
"GET /old-feed.rss HTTP/1.1" \
404 512 "-" \
"FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"
# Запрос к подкастному фиду:
66.249.85.13 - - [08/May/2026:20:16:00 +0000] \
"GET /podcast/feed.rss HTTP/1.1" \
200 124580 "-" \
"FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"
6.2 Аналитика через grep
Найти все запросы Feedfetcher:
grep -i 'FeedFetcher-Google' /var/log/nginx/access.log
Подсчитать количество запросов:
grep -i 'FeedFetcher-Google' access.log | wc -l
Какие фиды запрашиваются и как часто:
grep -i 'FeedFetcher-Google' access.log \
| awk '{print $7}' | sort | uniq -c | sort -nr
HTTP-коды ответов:
grep -i 'FeedFetcher-Google' access.log \
| awk '{print $9}' | sort | uniq -c | sort -nr
Запросы к несуществующим URL (404) — нужно исправить или перенаправить:
grep -i 'FeedFetcher-Google' access.log \
| awk '$9 == "404" {print $7}' \
| sort | uniq -c | sort -nr
Частота запросов по часам:
grep -i 'FeedFetcher-Google' access.log \
| awk '{print $4}' | cut -d: -f2 | sort | uniq -c | sort -n
Уникальные feedid — сколько разных фидов отслеживается:
grep -i 'FeedFetcher-Google' access.log \
| grep -o 'feedid=[^;)]*' | sort | uniq -c | sort -nr | head -20
Bandwidth — сколько данных скачивает бот:
grep -i 'FeedFetcher-Google' access.log \
| awk '{sum+=$10} END{print sum/1024/1024 " MB"}'
Live-мониторинг:
tail -f /var/log/nginx/access.log \
| grep --line-buffered -i 'FeedFetcher-Google'
6.3 Верификация подлинности
#!/bin/bash
# Проверка: настоящий ли Feedfetcher-Google?
IP=$1
HOST=$(host $IP | awk '{print $NF}')
if [[ $HOST == *googlebot.com* ]] || [[ $HOST == *google.com* ]]; then
FWD=$(host $HOST | awk '{print $NF}')
if [[ $FWD == $IP ]]; then
echo "✔ Настоящий Feedfetcher-Google: $IP → $HOST"
else
echo "✖ Fake Feedfetcher (DNS mismatch): $IP"
fi
else
echo "✖ Fake Feedfetcher-Google (нет PTR записи google.com): $IP"
fi
# Дополнительная проверка по официальному списку IP:
echo ""
echo "Проверка по user-triggered-fetchers-google.json..."
curl -s https://developers.google.com/static/search/apis/ipranges/user-triggered-fetchers-google.json \
| python3 -c "
import sys, json
data = json.load(sys.stdin)
ip = '$IP'
print('IP диапазоны Feedfetcher получены. Проверьте вручную:', ip)
"
7. Управление Feedfetcher-Google
7.1 Главное отличие: robots.txt не работает
⚠ Критически важно: Feedfetcher-Google — user-triggered fetcher. По официальной позиции Google, поскольку запросы инициированы реальными пользователями (которые подписались на фид через Google-сервис), агент действует как прямой представитель пользователя, а не автономный бот. Поэтому он игнорирует robots.txt.
Логика такова: если пользователь подписался на RSS-фид, то Google считает, что у пользователя есть право получать контент этого фида, и не позволяет robots.txt ограничить доступ к публичным фидам.
7.2 Единственный надёжный способ блокировки — HTTP-коды ошибок
Google официально рекомендует единственный работающий метод блокировки Feedfetcher: настроить сервер так, чтобы он возвращал код 404 Not Found или 410 Gone при запросе от User-Agent Feedfetcher-Google:
# Nginx — вернуть 410 Gone для Feedfetcher (рекомендует Google):
location /feed.rss {
if ($http_user_agent ~* "FeedFetcher-Google") {
return 410; # Gone — предпочтительнее 404, сигнализирует о постоянном удалении
}
# Остальные запросы обрабатываются нормально
}
# Или 404 Not Found:
location /feed.rss {
if ($http_user_agent ~* "FeedFetcher-Google") {
return 404;
}
}
# Блокировка всех фидов:
location ~* /feed {
if ($http_user_agent ~* "FeedFetcher-Google") {
return 410;
}
}
# Apache .htaccess — вернуть 410 для Feedfetcher:
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} FeedFetcher-Google [NC]
RewriteCond %{REQUEST_URI} ^/feed [NC]
RewriteRule .* - [R=410,L]
# Или через ErrorDocument:
RewriteCond %{HTTP_USER_AGENT} FeedFetcher-Google [NC]
RewriteRule ^feed\.rss$ - [R=404,L]
7.3 Почему 410 лучше, чем 404
| Код ответа | Значение | Поведение Feedfetcher |
|---|---|---|
| 200 OK | Фид доступен | Регулярно обновляет |
| 301 / 302 Redirect | Фид переехал | Следует по редиректу |
| 404 Not Found | Фид не найден | Повторяет попытки (может быть временным) |
| 410 Gone | Фид удалён навсегда | Прекращает попытки (постоянное удаление) |
| 403 Forbidden | Доступ запрещён | Повторяет попытки реже |
| 503 Service Unavailable | Временно недоступен | Повторяет попытки позже |
7.4 robots.txt — ограниченная эффективность
Хотя официально robots.txt не работает, некоторые владельцы сайтов добавляют записи как дополнительный сигнал:
# Попытка блокировки через robots.txt (официально не работает):
User-agent: FeedFetcher-Google
Disallow: /feed.rss
User-agent: Feedfetcher-Google
Disallow: /
# ВНИМАНИЕ: Google официально подтверждает, что Feedfetcher
# игнорирует эти директивы.
# Единственный надёжный метод — HTTP 404/410 по User-Agent.
7.5 Переадресация устаревших фидов
Если фид переехал на новый URL, используйте постоянный редирект:
# Nginx — постоянный редирект фида:
location = /old-feed.rss {
return 301 https://example.com/new-feed.rss;
}
# Для Feedfetcher — лучше уведомить через rel="self":
# Обновите <atom:link rel="self" href="https://example.com/new-feed.rss"/>
# в содержимом фида — Feedfetcher обновит подписку автоматически
8. Оптимизация RSS/Atom фидов
8.1 Валидность XML — основа всего
Невалидный XML — самая частая причина, по которой Feedfetcher не может прочитать фид:
<!-- ✖ Частые ошибки в XML фидов: -->
<!-- Ошибка 1: Спецсимволы без экранирования -->
<title>Статья о C++ & Python</title> <!-- & должен быть & -->
<title>Статья о C++ & Python</title> <!-- ✔ правильно -->
<!-- Ошибка 2: HTML в description без CDATA -->
<description><p>Текст</p></description> <!-- теги сломают XML -->
<description><![CDATA[<p>Текст</p>]]></description> <!-- ✔ -->
<!-- Ошибка 3: Неверный формат даты -->
<pubDate>2026-05-08</pubDate> <!-- не RFC 2822 -->
<pubDate>Thu, 08 May 2026 14:30:00 +0300</pubDate> <!-- ✔ RFC 2822 -->
<!-- Ошибка 4: Отсутствие UTF-8 декларации -->
<!-- Убедитесь что файл в UTF-8 БЕЗ BOM -->
<?xml version="1.0" encoding="UTF-8"?> <!-- обязательно -->
8.2 Проверка валидности фида
# Онлайн-валидаторы:
# https://validator.w3.org/feed/
# https://www.feedvalidator.org/
# Локальная проверка через xmllint:
curl -s https://example.com/feed.rss | xmllint --noout -
# Нет вывода = XML валиден
# Проверка через Python:
python3 -c "
import feedparser
feed = feedparser.parse('https://example.com/feed.rss')
print(f'Версия: {feed.version}')
print(f'Записей: {len(feed.entries)}')
if feed.bozo:
print(f'Ошибка: {feed.bozo_exception}')
else:
print('Фид валиден!')
"
8.3 Оптимальная структура фида для Google-сервисов
<!-- Чеклист оптимального RSS-фида: -->
<!-- 1. Правильная кодировка -->
<?xml version="1.0" encoding="UTF-8"?>
<!-- 2. Нужные namespace -->
<rss version="2.0"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:media="http://search.yahoo.com/mrss/"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<!-- 3. Обязательные метаданные канала -->
<channel>
<title>Название</title>
<link>https://example.com</link>
<description>Описание</description>
<language>ru</language>
<lastBuildDate>Thu, 08 May 2026 14:30:00 +0300</lastBuildDate>
<atom:link rel="self" type="application/rss+xml"
href="https://example.com/feed.rss"/>
<atom:link rel="hub"
href="https://pubsubhubbub.appspot.com/"/>
<!-- 4. Записи с полными данными -->
<item>
<title>Точный заголовок без кликбейта</title>
<link>https://example.com/article/</link>
<guid isPermaLink="true">https://example.com/article/</guid>
<pubDate>Thu, 08 May 2026 14:30:00 +0300</pubDate>
<dc:creator>Иван Иванов</dc:creator>
<description><![CDATA[Краткое описание...]]></description>
<content:encoded><![CDATA[Полный HTML...]]></content:encoded>
<media:thumbnail url="https://example.com/thumb.jpg"
width="1200" height="630"/>
<category>Технологии</category>
</item>
</channel>
</rss>
8.4 Количество записей в фиде
| Рекомендация | Детали |
|---|---|
| Оптимальное количество записей | 20–50 последних публикаций |
| Максимум разумного размера | До 5 MB без сжатия (после gzip — значительно меньше) |
| Минимум для активного издания | Не менее 10 записей |
| Частота обновления | Каждую публикацию — пинговать PubSubHubbub |
| Старые записи | Не удалять из фида — только сдвигать в конец |
9. Диагностика проблем
9.1 Типичные проблемы и решения
| Проблема | Причина | Решение |
|---|---|---|
| Feedfetcher не читает фид | Невалидный XML или неверный Content-Type | Валидировать через W3C Feed Validator |
| Фид обновляется медленно в Google News | Нет PubSubHubbub — только polling | Настроить PubSubHubbub и пинговать хаб при публикации |
| Feedfetcher запрашивает несуществующий URL | Пользователь подписался на неверный URL | Вернуть 410 Gone для Feedfetcher по этому URL |
| Слишком частые запросы к одному фиду | Сетевые задержки или перезапуск серверов Feedfetcher | Поддержать conditional requests (ETag/Last-Modified) |
| Feedfetcher получает 404 на валидный фид | Неверная конфигурация сервера или блокировка по UA | Проверить nginx/apache конфиг, убрать ошибочную блокировку |
| Подкаст не индексируется в Google Search | Ошибки в структуре RSS: нет enclosure или itunes-тегов | Проверить через Podcast Manager в Google Search Console |
| Фид виден в логах, но контент устарел в News | Content-Type не XML или фид кешируется слишком долго | Установить Content-Type: application/rss+xml, снизить TTL кеша |
9.2 Проверка Content-Type фида
# Проверить Content-Type заголовок:
curl -I https://example.com/feed.rss
# Правильные значения Content-Type для фидов:
# application/rss+xml (RSS 2.0 — рекомендуется)
# application/atom+xml (Atom 1.0 — рекомендуется)
# text/xml (принимается, но не оптимально)
# application/xml (принимается)
# Nginx — установить правильный Content-Type:
location /feed.rss {
default_type application/rss+xml;
charset utf-8;
}
location /feed.atom {
default_type application/atom+xml;
charset utf-8;
}
9.3 Симуляция запроса Feedfetcher
# Проверить доступность фида для Feedfetcher:
curl -A "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)" \
-I https://example.com/feed.rss
# Ожидаемый результат:
# HTTP/1.1 200 OK
# Content-Type: application/rss+xml; charset=UTF-8
# Скачать и проверить содержимое:
curl -A "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)" \
https://example.com/feed.rss | xmllint --noout -
# Проверить поддержку условных запросов:
ETAG=$(curl -sI https://example.com/feed.rss | grep -i ETag | awk '{print $2}')
curl -A "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)" \
-H "If-None-Match: $ETAG" -I https://example.com/feed.rss
# Если фид не изменился — должен вернуть 304 Not Modified
9.4 Инструменты для диагностики фидов
- W3C Feed Validator — validator.w3.org/feed/ — проверка RSS/Atom на соответствие стандарту
- Google Rich Results Test — search.google.com/test/rich-results — проверка структурированных данных
- Google Podcast Manager — podcastsmanager.google.com — статус индексации подкастов
- PubSubHubbub хаб — pubsubhubbub.appspot.com — проверка подписок и пинг хаба
- Google Publisher Center — publishercenter.google.com — управление присутствием в Google News
10. Feedfetcher-Google vs другие RSS-агрегаторы
| Сервис / Агент | User-Agent | Тип | robots.txt |
|---|---|---|---|
| Feedfetcher-Google | FeedFetcher-Google |
User-triggered fetcher | ✖ Игнорирует |
| Feedly | Feedly/1.0 |
RSS-агрегатор | ✔ Уважает |
| Inoreader | Inoreader/... |
RSS-агрегатор | ✔ Уважает |
| Bloglovin | Bloglovin |
RSS-агрегатор | ✔ Уважает |
| NewsBlur | NewsBlur Feed Fetcher |
RSS-агрегатор | ✔ Уважает |
FlipboardProxy/... |
Контентный агрегатор | ✔ Уважает | |
| Yandex.News Bot | YandexNews/1.0 |
Краулер новостей | ✔ Уважает |
| Apple News | AppleNewsBot |
Новостной агрегатор | ✔ Уважает |
Пример robots.txt для управления RSS-агрегаторами:
# Разрешить все легитимные агрегаторы:
User-agent: *
Allow: /feed.rss
Allow: /feed.atom
# Заблокировать AI-харвестеры, но оставить агрегаторы:
User-agent: GPTBot
Disallow: /
User-agent: CCBot
Disallow: /
User-agent: Bytespider
Disallow: /
# Feedfetcher-Google: robots.txt не работает,
# используйте HTTP 410 на уровне сервера если нужна блокировка
11. Рекомендуемая стратегия
✔ Главный принцип: Feedfetcher-Google — ваш канал доставки контента в Google-экосистему. Правильно настроенный RSS/Atom фид с PubSubHubbub — самый быстрый способ доставить новый контент в Google News. Не блокируйте, а оптимизируйте.
| Задача | Решение |
|---|---|
| Ускорить появление контента в Google News | Настроить PubSubHubbub + пинговать хаб при каждой публикации |
| Обеспечить корректное чтение фида | Валидный XML + правильный Content-Type + UTF-8 без BOM |
| Снизить нагрузку от Feedfetcher | ETag/Last-Modified + gzip + Cache-Control для фида |
| Заблокировать Feedfetcher надёжно | HTTP 410 Gone при User-Agent Feedfetcher-Google (не robots.txt) |
| Перенести фид на новый URL | 301 редирект + обновить rel="self" в фиде |
| Убрать запросы к несуществующим URL | HTTP 410 Gone для устаревших URL фидов |
| Индексировать подкаст в Google Search | Правильный RSS с enclosure + itunes-теги + Google Podcast Manager |
| Проверить работоспособность фида | curl + xmllint + W3C Feed Validator |
| Обнаружить активность в логах | grep 'FeedFetcher-Google' + анализ feedid |
| Верифицировать подлинность бота | DNS lookup + сверка с user-triggered-fetchers-google.json |