HTTP-заголовки страницы
Сначала немного информации для тех, кто так и не удосужился разобраться в протоколе HTTP. К сожалению, таких все больше – программирование на php не представляет большой трудности, велик соблазн взяться сразу за написание скрипта, а во все «тонкости и хитрости» среды не вникать. Или срисовать что-нибудь готовое, приспособив к своим нуждам. Вот так и кочуют из одного скрипта в другой чьи-то застарелые ошибки.
Что происходит, когда вы запрашиваете какую-то страницу сайта? Отбросим все тонкости поиска сервера в сервисах доменных имен – сейчас речь не об этом – и остановимся на невидимом «диалоге» клиента с сервером. Ваш браузер посылает серверу запрос (HTTP Request). В нем браузер передает имя хоста (домен с www или без), запрашиваемый документ (с маршрутом от корня сайта), ожидаемый медиатип, возможность приема сжатого формата, ожидаемый язык документа и свое наименование (User-Agent).
Получив запрос, сервер ищет документ и отвечает. Ответ состоит из заголовка (HTTP Response Header) и «тела» документа. Заголовок – это ответ на запрос и несколько строк сопроводительной информации к документу. Главная часть заголовка – код статуса. Это «200 OK», если запрошенный документ найден по данному адресу и подготовлен к отправке. Другие коды статуса сообщают об ошибке или дополнительных условиях передачи документа. Не буду размещать здесь справочник по кодам статуса, его вы найдете, например, в подсказках к Google Webmaster Tools или в FAQ Яндекса для вебмастера.
Самое главное – обмен информацией с роботом поисковой системы идет точно так же, как и с браузером. С единственным отличием – поисковые роботы отправляют только запросы GET (получить документ) или HEAD (получить только заголовок). Но POST-запросы (передачу информации в форме и получение страницы результата) роботы не посылают никогда. Формы они не заполняют и на кнопки не жмут. :-)
На более поздней модификации этого же движка сделан экспериментальный сайтик, в который встроена небольшая добавка – он фиксирует визиты роботов и пишет в логи HTTP-запросы. Теперь у меня есть достаточно богатый материал по взаимодействию с ПС. Когда я допишу эту статью и сделаю ссылку на страницу видимой, робот Google обнаружит эту ссылку в меню и придет за страницей. Диалог робота с сайтом будет выглядеть так:
Робот:
GET /headers.ahp HTTP/1.0 Accept: */* Accept-Encoding: gzip,deflate Connection: Keep-alive From: googlebot(at)googlebot.com Host: www.ahp-net.ru User-Agent:Mozilla/5.0 (compatible; Googlebot/2.1;http://www.google.com/bot.html)
Сайт:
HTTP/1.1 200 OK Server: nginx/0.5.32 Date: Sat, 20 Jun 2009 20:54:32 GMT Content-type: text/html; charset=windows-1251 Transfer-encoding: chunked Connection: keep-alive X-powered-by: PHP/5.2.8
С ботом Google все просто. Он принимает любые медиатипы (Accept: */*), допускает сжатый формат передачи (gzip), язык документа не запрашивает. Остается добавить, что когда он придет за этой же страницей в следующий раз, в заголовке запроса будет еще одна строка:
If-Modified-Since: Sat, 20 Jun 2009 20:54:32 GMT
Это прозрачный намек робота, что если с прошлого визита страница не менялась, можно послать код статуса «304 Not Modified» и страницу не передавать. Зачем ему заново перечитывать ту же страницу, время – деньги. И трафик тоже.
С индексирующим роботом Яндекса дело обстоит несколько иначе. Он более точно формулирует свои запросы. Например, когда он придет считывать эту же страницу, заголовок запроса будет таким:
GET /headers.ahp HTTP/1.0 Accept: text/html, application/pdf;q=0.1, application/rtf;q=0.1, text/rtf;q=0.1, application/msword;q=0.1, application/x-shockwave-flash;q=0.1, application/vnd.ms-excel;q=0.1, application/vnd.ms-powerpoint;q=0.1 Accept-Encoding: gzip,deflate Accept-Language: ru, uk;q=0.8, be;q=0.8, en;q=0.7, *;q=0.01 Connection: Keep-Alive From: webadmin@yandex.ru Host: www.ahp-net.ru User-Agent: Yandex/1.01.001 (compatible; Win16; I)
Переносов в строке Accept: нет – я их наделал, потому что строка слишком длинная. Обратите внимание, Яндекс не так всеяден. Его интересуют документы html и в гораздо меньшей степени еще несколько типов, но отнюдь не все подряд. Он также согласен принимать данные в сжатом gzip формате. Но в его заголовках мы видим и предпочтение языку документа. Его интересует русский язык, в несколько меньшей степени украинский и белорусский, еще меньше английский, и совсем мало – все остальные. В последующие визиты Яндекс также будет запрашивать If-Modified-Since, чтобы не перечитывать много раз одно и то же.
Со времени написания статьи в запросах Яндекса дважды были изменения. Сначала он расширил список допустимых медиатипов примерно вдвое, а с 10 ноября 2009 г. значение Accept: стало выглядеть как и у Google – */*. То есть, сейчас бот Яндекса принимает все медиатипы.
Робот Рамблера пошлет самый простой запрос:
GET /headers.ahp HTTP/1.0 Connection: keep-alive From: search.support@rambler-co.ru Host: www.ahp-net.ru User-Agent: StackRambler/2.0 (MSIE incompatible)
Как видите, здесь нет ни ожидаемых медиатипов, ни языковых предпочтений. Рамблер изначально работает с русскоязычным контентом и ограниченно – с англоязычным. Распознает медиатипы и кодировки автоматически.
Со времени написания статьи и поиск Рамблера и его поисковый робот прекратили свое существование. Теперь на Рамблере работает поиск Яндекса и следов поискового бота StackRambler мы в логах больше не увидим. А жаль...
Отклик сервера во всех случаях будет аналогичным, так что нет смысла повторяться.
Не следует воспринимать приведенные заголовки этого сайта как образец. Сайт делался на относительно сырой версии движка, которая с тех пор во многом изменилась и продолжает изменяться. Так что в работе с заголовками у него многого не хватает. Со временем будет исправлено. Но необходимый минимум для нормального взаимодействия с поисковыми системами он отдает.
Вот такая пища для размышлений. А выводы из всего этого и конкретные рекомендации – в следующий раз. Продолжение следует...