Семантическая сеть. Часть 4

March 22, 2008

Сегодня я продолжу и завершу рассмотрение технологий, составляющих основу Семантической Паутины. В прошлой статье я начал рассказ об одной из наиболее популярных (и уже нашедших практическое применение в ряде веб-приложений) технологий – FOAF. FOAF позволяет нам создавать описания “своего профиля”, указывать то, с какими сайтами или документами вы взаимосвязаны, и (самая “соль” технологии) указывать “дружеские” отношения с другими участниками сети.

Однако перед тем как я перейду к рассмотрению программных средств позволяющих находить и визуализировать FOAF-информацию, рассмотрим смежную с FOAF технологию - XFN. XFN расшифровывается как XHTML Friends Network. Из названия следует, что эта технология также служит для описания социальных сетей (являясь неким аналогом FOAF), но в ее основе лежит XHTML. Для создания FOAF-документов мы использовали XML-синтаксис по правилам RDF. Нельзя сказать, что эти технологии (XML, RDF) сложны: написав десяток RDF-документов можно их “клепать” практически не задумываясь (подлежащие, сказуемое, дополнение). Грамматики (список определенных тегов для описания некоторой предметной области) уже достаточно стабильны, чтобы не бояться, будто стандарты пересмотрят и все, сделанное ранее, будет утеряно. Я вижу проблему в двух вещах: отсутствие ярких и работающих приложений, показывающих массовому пользователю силу Semantic Web. Вторая проблема – сложность добавления к традиционному Web-у семантической разметки. Действительно, мы должны фактически создать и поддерживать два параллельных документа: внося изменения в html-документ, вносим их и в RDF-файл – это может быть слишком утомительно. Отсутствие “в одно нажатие мыши” поддержки RDF в средствах веб-разработки (и редакторы html, и движки сайтов, форумов, блог-платформ) отпугивают многих из желающих познакомиться с Semantic Web. Со временем, ситуация должна поменяться, но лучше поговорим о сегодняшнем дне и уже существующих подходах к внедрению семантических данных в html-документы. Здесь нам помогут микроформаты, одним из ярких представителей которых и является XFN. Идея микроформатов носит эволюционный характер и говорит: нам не нужны отдельные RDF-документы, мы не хотим тратить силы на согласование html и RDF-содержимого, давайте лучше “упакуем” семантическую информацию внутрь обычного html-файла. Действительно, когда вы создаете страничку на сайте со своей биографией и перечнем друзей, то размечаете ее с помощью html-тегов, назначаете этим тегам стили CSS (визуальная сторона информации). В первой статье серии я рассказывал про ряд тегов ACRONYM, CITE, ADDRESS, которые могли бы быть использованы для логической разметки информации, но у них не сложилось, в основном из-за незрелости более актуальных на тот момент средств визуализации. Сейчас верстальщики в массе своей уже осознали, что только благодаря четкой структуре информации (логической) и вынесению средств визуализации в отдельный файл CSS, можно ускорить верстку сайтов. Можно снизить издержки на поддержку и доработку сайта, смену дизайна, добавление новых функций так, чтобы не происходило подобного: “ой, мы только добавили в углу страницы баннер, и весь сайт поломался”. Прекрасно, значит, когда я создал блок “div” внутри которого будет храниться мое ФИО, и назначил для этого блока некоторый CSS-класс для красивого оформления я уже подготовил данные для последующей “семантизации”. Что если я добавлю к этому блоку div еще один css-класс, пусть даже без визуального оформления, но с заранее оговоренным именем, например, myfio. Тогда любое веб-приложение “вытянув” страничку сможет определить, что содержимое некоторого абзаца имеет семантическое значение ФИО автора страницы. Именно эта идея легла в основу микроформатов. Гибкость микроформатов в том, что мы не создаем новые теги, например, price, fio, boss, и не ждем тысячу лет, пока они будут реализованы разработчиками браузеров. Так, чтобы попытка вставить в текст страницы ссылку на свое “fio” не привела к “падению” верстки сайта. К счастью в составе стандарта html/xhtml изначально были предусмотрены точки расширения – это атрибуты rel, rev и class. Например, rel – это атрибут для ссылки “a” или “link”. И его назначение - указать на то “какая это ссылка?”. Так, ссылка <a href="http://site.ru" rel="home">home</a> говорит, что для текущей страницы сайта домашней страницей является расположенная по адресу http://site.ru. Если вы откроете этот адрес в firefox с установленным плагином https://addons.mozilla.org/ru/firefox/addon/1324 или в opera, то вы увидите строку меню с перечислением “связанных” страниц. Однако не будем отходить от темы, а вернемся назад к описанию социальной сети с помощью XFN. Публикуя информацию на странице сайта о своих друзьях, сотрудниках, семье вы создаете ссылки на их персональные странички. А давайте к каждой ссылке добавим атрибут rel и перечислим через пробел список ключевых слов, подсказывающий кто это, и как связан с нами. Например, следующий пример говорит, что по адресу http://jim.ru расположена страничка описывающая меня:
  1. <a href="http://jim.ru" rel="me">jim</a>
Если ссылка идет на другое лицо, то можно указать на вид взаимоотношений с ним, используя перечисленные ниже в табличке ключевые слова:
Ключевое слово Значение
friend acquaintance contact Укажите одно из значений: друг, просто знакомый, человек которого вы знаете, как найти.
met С этим человеком вы лично встречались
co-worker colleague С этим человеком вы работаете в одной организации и, второй вариант, это ваш коллега.
co-resident neighbor А это фактор географического расположения. В первом случае вы живете в одном городе или на одной улице. Во втором случае – вы соседи.
child parent sibling spouse kin Семейные отношения: ваш ребенок, ваши родители, брат или сестра, затем супруг и, наконец, просто родственник.
muse crush date sweetheart Ваша муза, тот к кому вы испытываете страстное влечение, тот с кем вы встречаетесь и, наконец, ваш возлюбленный или возлюбленная.
me Это я. Все остальные значения атрибутов является недопустимыми.
Например:
  1. <a href="lenka.ru" rel="friend colleague met neighbor date ">.
Это Ленка, мы работаем вместе, живем в соседних квартирах и встречаемся.

Создать XFN-ссылки очень легко, хотя может кому-то пригодится и online-генератор http://gmpg.org/xfn/creator. Теперь перейдем к вопросу извлечения XFN и FOAF информации с последующей ее обработкой и визуализацией. На просторах сети мне попался занимательный пример отображения FOAF-сведений в виде интерактивного графа http://apassant.net/home/2008/01/foafgear/ (в основе этого приложения лежит написанная на flash и довольно-таки универсальная библиотечка для построения графов graph-gear). Если у вас есть FOAF профиль, распложенный не на одном из “тяжелых сайтов” вроде ЖивогоЖурнала (следующий сервис блокирует ряд сайтов), то вы можете попробовать его ввести в форму http://xml.mfd-consult.dk/foaf/explorer/, затем данные из foaf файла будут визуализированы (пусть не в виде графа, но все равно удобно). Еще может быть интересен проект ljnet (http://patrickbarry.com/projects/ljnet/index.php). Эта программа написана на java, так что для корректной работы потребуется sun jre, также для работы требуется установленный quicktime.

Последняя технология, о которой я должен упомянуть перед переходом к “немного попрограммировать” – это openid. Идея универсального идентификатора для каждого пользователя сети была заманчива всегда, в особенности для предприятий занятых в сфере электронной коммерции и всевозможных спец.служб. Я вспоминаю давнишний скандал с выпуском на рынок процессоров Pentium III с внедренным серийным номером. Представители Intel рассказывали, что уникальные идентификационные номера повысят безопасность, критики заявили о нарушении конституционных свобод, о том, что недобросовестные компании в корыстных целях используют информацию о том, какие сайты посещают пользователи. Периодически на страницы как электронной, так и периодической печати пробиваются всплески “ужаса”, посвященные все новым сферам применения RFID-меток, уже не только для того чтобы “пометить” товары в магазине или поместить чип под кожу животным, но и о том, как эти метки будут (были, уже давно были) внедрены в тело человека. Однако забудем об ужасах Большого Брата и рассмотрим сложившуюся ситуацию в internet. Как известно в internet множество сайтов, форумов, блогов. Для того чтобы активно жить в сети: читать статьи, комментировать, вы должны быть зарегистрированы. А как же иначе? Ведь, если разрешить писать сообщения в свой блог всем подряд, то его элементарно замусорят спамом. “Черные” оптимизаторы бродят по просторам сети и оставляют в первых попавшихся блоках дурацкие комментарии с ссылкой на рекламируемый сайт. Уважаемые горе-оптимизаторы, прочитайте, наконец, google FAQ и запомните, что “a” ссылки с атрибутом “rel=nofollow” (стандартная настройка почти всех блогов и CMS-ок) не учитываются при расчете рейтинга вашего сайта. Итак, регистрация на сайте нужна, давайте рассмотрим ее методику. Мы придумываем login (так, вариант petya занят, значит, пробуем petya2, petya.kozlov, только бы не забыть), теперь нужен пароль (так, мой стандартный пароль 123 не подходит по длине, значит здесь пароль будет 12345), затем email (так, где мой ящик для спама?), затем имя, адрес, дата рождения … И самое главное, ведь не на всякий сайт вы будете посещать ежедневно и спустя некоторое время вы забываете свои учетные данные. Помимо опасности забыть (ведь это так сложно, воспользоваться встроенным в браузер менеджером паролей), часто бывает просто лень предварительно регистрироваться на каком-то из “мириада” блогиков чтобы написать одно сообщение. Люди, активно живущие в сети, бывают озабочены тем, чтобы их “писанина” не потерялась и всегда была ассоциирована именно с ними любимыми (действительно, как ассоциировать vasya.kozlov на сайте site.ru с vasya123 на сайте site.com). Конечно, таких людей крайне мало, но проблема уникальной (и, главное, сквозной для множества сайтов) идентификации есть и давайте рассмотрим методику ее решения. Наиболее известны: microsoft passport, openid, cardspace, typekey. Каждая из технологий имеет свои плюсы и минусы, обусловленные подходом к решению трех целевых задач безопасности. Сказку про сложность регистрации и забывание паролей я не повторяю. Итак: защита от Fraud-ов (например, злоумышленники подменивают сайт, на котором вы вводите пароль). Далее: обеспечение privacy (если для посещения некоторого сайта требуется предварительно обратиться к поставщику идентификации за именем и паролем, то этот сайт поставщика может выполнять сбор сведений о том, какие сайты мы посещаем для своих целей). И последний фактор - Trust (доверие к поставщику). Как сайт-клиент системы аутентификации может принять решение о том, доверять ли пользователю, пришедшему от некоторого провайдера аутентификации? Системы typekey и passport построены как централизованные сервисы, т.е. база данных пользователей хранится в пределах одной организации, к которой выполняется обращение за подтверждением подлинности пользователя от некоторого сайта-клиента. Такой подход обеспечивает худо-бедно защиту от Fraud-ов, и решает вопрос доверия сайта клиента сервису аутентификации, а вот вопрос privacy остается открытым. На территории бывшего СССР и typekey и passport не распространены, вместо них используются openid и такие сервисы как “yandex.Паспорт”.

Openid - эта система децентрализованная … и в ней вопрос обеспечения защиты от Fraud-ов, Trust, Privacy, в принципе, не ставится. Идея в том, что всякий массовый сервис, который выполняет регистрацию пользователей (например, ЖивойЖурнал) выдает пользователю персональную страничку, на которой находятся специальные html-теги содержащие сведения об адресе сервера (правильнее говорить провайдера openid). Затем, когда вы заходите на какой-то блог, то можете при отправке формы комментария к сообщению, не регистрироваться, а указать в специальном поле ваш openid-идентификатор. Например, мой openid это http://blackzorro.livejournal.com/. Затем выполняется автоматический переход на сайт провайдера openid, где нас спрашивают доверяем ли мы сайту запросившему аутентификацию и какие из персональных данных мы хотим указать при этом: имя, email, страна, пол … Если мы подтверждаем и говорим: “да, я доверяю этому сайту”, то выполняется обратный переход и в отправленное сообщение подставляются данные взятые от openid-провайдера (вам не нужно повторно вводить свои персональные данные). Провайдер openid запоминает ваш выбор, так что при последующих посещениях сайта процедура аутентификации может быть выполнена “в один клик”. В прошлой статье, когда я описывал возможности FOAF, то упомянул о существовании тега foaf:openid. В следующем примере я показываю совместное использование этих двух технологий:
  1. <foaf:Person>
  2.   <foaf:name>Вася Тапкин</foaf:name>
  3.   <foaf:mbox rdf:resource="mailto:vasyano@site.ru" />
  4.   <foaf:openid>tapkin.livejournal.com</foaf:nick>
  5.  </foaf:Person>
Теперь попробуем написать немного кода работающего с google social api (http://code.google.com/apis/socialgraph/docs/). Когда поисковый робот google исследует сеть и создает обычный индекс (html-страниц), то одновременно с этим строится и дополнительный индекс на основании FOAF-профилей и XFN-вставок. Результаты могут быть запрошены с помощью специального набора функций API. В прошлой статье я упомянул о прошедшей в начале февраля презентации этого сервиса. Google и Brad Fitzpatrick рассказывали о сферах применения API, рисовали на доске Социальные Сети, и обещали, что теперь вы можете легко переносить находить “друзей” по одному сервису на другом сайте. Пользоваться API очень легко: нужно отправить http-запрос специального вида по адресу http://socialgraph.apis.google.com/lookup. Обмен данными идет с помощью JSON (об этом формате я многократно писал в статьях посвященных javascript). А, следовательно, доступ к сервису google может быть выполнен почти из любого современного языка программирования. Рассмотрим как выглядят полученные от google данные? Социальный Граф возвращается в форме … графа. Т.е. мы получаем список узлов и граней связывающих их. Узел - это отдельная персона (точнее ее профиль на каком-либо сайте). У узла есть характеристики (url, profile, rss, atom, foaf, photo). Пару слов относительно первого параметра – главного адреса персоны (второй параметр profile содержит ссылку на страничку с описанием, профилем человека). Так вот, т.к. существует множество всевозможных сайтов, где может быть зарегистрирован наш человек и адреса персональных страничек могут быть в различном виде (vasya.site.ru, site.ru?vasya, site.ru/users/vasya), то было принято решение о введении SGN (стандартная общая форма нотации некоторой фиктивной социальной сети где будто бы зарегистрированы все на свете люди). С другой стороны вы можете отказаться от услуги SGN ификации адресов и вернуть их как есть (если google ничего не знает о системе имен на некотором сайте, то он их не подвергает SGN-ификации). Каждый узел может быть связан с другими узлами некоторыми отношениями и их перечень совпадает с … перечисленными выше типами отношений XFN. Для примера я позаимствовал следующий профиль http://perso.hirlimann.net/~ludo/blog/ и ввел его в форму тестового приложения google social graph (http://socialgraph-resources.googlecode.com/svn/trunk/samples/exploreapi.html). Там же я отметил галочками такие параметры поиска как “отображать me-ссылки”, показывать “входящие” ссылки и показывать “исходящие” ссылки. После чего открылась новая страница с адресом:
1) http://socialgraph.apis.google.com/lookup?
2) q=http%3A%2F%2Fperso.hirlimann.net%2F%7Eludo%2Fblog%2F&
3) fme=1&edi=1&edo=1&pretty=1&sgn=1&callback=parse
Первая строка – это, собственно адрес сервиса google выполняющего поиск информации. Вторая строка содержит значение переменной “q” равной адресу блога человека, о котором я хочу найти все сведения. И третья строка содержит опции поиска (все последующие переменные являются логическими, т.е. 1 – включено, 0 - отключено).

Fme– будут ли возвращены ссылки на страницы, помеченные как мои (<a href="vasya.ru" rel="me">). Переменная edo - признак поиска исходящих от меня узлов. Переменная edi – признак поиска входящих узлов. Значение параметра sgn я описал выше, а параметр pretty служит для того, чтобы полученные данные красиво визуализировать (в любом случае формат ответа от google – JSON, но с модификатором pretty результат будет смотреться более “человекочитаемо”). Последний параметр “callback=parse” говорит о том, после того как данные от google были загружены, то автоматически будет вызвана javascript-функция по имени parse. Вот небольшой фрагмент ответа google:
  1. parse({
  2.  "canonical_mapping": {
  3.         "http://perso.hirlimann.net/~ludo/blog/": http://perso.hirlimann.net/~ludo/blog/"
  4.  },
  5.  "nodes": {
  6.         "http://en.wikipedia.org/wiki/SPARQL": 
  7.             { 
  8.               "attributes": {},
  9.               "claimed_nodes": [ ], 
  10.               "unverified_claiming_nodes": [ http://advogato.org/person/softkid/diary.html?start\u003d95" ],
  11.               "nodes_referenced": { },
  12.               "nodes_referenced_by": {"http://advogato.org/person/softkid/diary.html?start\u003d95": {"types": ["me"]},
  13.  ......
Здесь говорится, что узел http://en.wikipedia.org/wiki/SPARQL взаимосвязан с адресом http://perso.hirlimann.net/~ludo/blog/. И хотя при этом список атрибутов узла (url, profile, rss …) пуст, но зато есть отношения связи с другими узлами. “claimed_nodes” – здесь перечень узлов (пустой), которые находятся в симметричном отношении rel=”me”, т.е. и первый и второй сайт ссылаются друг на друга и говорят: ”это я, это сайт одного автора”. Список “unverified_claiming_nodes” говорит, что один из узлов заявил об авторстве, но второй этого не подтвердил. Список “nodes_referenced” – перечень узлов, на которые идет исходящая ссылка, а список “nodes_referenced_by” – с каких сайтов пришли ссылки на страницу http://en.wikipedia.org/wiki/SPARQL

На этом все. Конечно же, тема Semantic Web очень большая, и о многом можно рассказать: о тех же микроформатах и об обещанном мною SPARQL. Но, наверное, это будет только спустя какое-то время.