Содержание


Преобразование списков Twitter в ленту RSS

Интерпретация ленты публикаций из виджета списка Twitter и ее развертывание в Bluemix для всеобщего использования

Comments

Социальная сеть Twitter предлагает пользовательские виджеты для встраивания ленты сообщений Twitter в веб-сайт. Ленты можно составлять на основе любых источников, в том числе своих собственных твитов или отметок "Нравится", одного из списков Twitter или результатов поиска. Сразу после запуска Twitter в 2006 году виджеты могли генерировать ленты публикаций в нескольких форматах, в том числе XML, Atom, JSON и RSS. Но с выходом API версии 1.1 в сентябре 2012 года все форматы, кроме JSON, были объявлены нерекомендуемыми.

Возможно, вам, как и мне, больше всего было жаль потерянной возможности использовать RSS. Этот формат был ценен тем, что позволял читать ленту сообщений с помощью почтовых клиентов, расширений браузера или специализированных программ для чтения RSS-лент. Кроме того, RSS легко интегрируется с сервисом рецептов IFTTT.com для целей автоматизации

Однако любителям RSS нетрудно помочь. Используя это руководство, вы создадите простой сценарий Node.js для интерпретации ленты публикаций в формате JSON из виджета Twitter и возврата ее в формате RSS. Этот сценарий использует вызов REST, чтобы получить ленту виджета, интерпретирует ее с помощью модуля node-elementtree и возвращает результат в виде ленты RSS из маршрута Express .

На заключительном этапе вы выполните развертывание ленты RSS в IBM Bluemix, чтобы предоставить пользователям возможность читать ее в браузере или подписываться на нее с помощью других программ. В рамках этого руководства вы будете работать с виджетом списка Twitter, но аналогичный подход можно применить и к виджетам, созданным на основе любого источника публикаций Twitter.

Вам понадобится

Запустить приложениеПолучить код

Шаг 1. Создайте список Twitter

Используя браузер на настольной системе, войдите в Twitter со своей учетной записью. Щелкните на фото профиля в правом верхнем углу страницы и выберите в меню команду Lists (Списки) . Вы увидите имеющиеся списки (если они у вас есть) и кнопку Create new list (Создать новый список) . Чтобы создать новый список по вашему выбору, следуйте инструкциям по следующей ссылке:

Для этого руководства я создал список Writers который содержит страницы моих любимых писателей в Twitter:

Screenshot of Twitter list
Screenshot of Twitter list

Шаг 2. Создайте виджет Twitter

  1. Щелкните на фото своего профиля Twitter и выберите команду Settings (Настройки).
  2. На странице настроек выберите команду Widgets в меню слева и нажмите кнопку Create new (Создать новый)..
  3. Из вариантов под заголовком Choose a timeline source (Выберите источник хроники) , выберите List (Список), укажите список, который вы создали на этапе Шаг 1, и нажмите кнопку Create widget (Создать виджет). Через несколько секунд вы увидите в текстовом поле HTML-код внедрения для виджета.
  4. Скопируйте этот код куда-нибудь и обратите внимание на значение data-widget-id из тега привязки.

Шаг 3. Получите ленту сообщений виджета

  1. Создайте в своей системе пустой каталог и перейдите в него.
  2. Из командной строки используйте npm, чтобы создать новый проект Node.js :

    npm init

    В большинстве случаев вполне подходит значение по умолчанию. (Обратите внимание, что в последней версии npm имя проекта не должно содержать символов в верхнем регистре).
  3. Из командной строки добавьте к проекту модуль request (он является фактическим стандартом для клиентов Node REST clients):

    npm --save install request

    Необязательный флаг --save добавляет этот модуль к зависимостям проекта в package.json, чтобы вам не понадобилось добавлять его в файл вручную.
  4. Создайте пустой файл для кода сценария и дайте ему имя, совпадающее со значением атрибута main в файле package.json — как правило, это index.js. Добавьте в index.js следующий код, заменив <widget ID> 4. значением идентификатора виджета, которое вы сохранили на этапе Шаг 2:
    var request = require('request');
    
    request.get("http://cdn.syndication.twimg.com/widgets/timelines/<widget ID>",
    	function(err, resp, body) {
    
    });

    В предыдущем фрагменте кода все виджеты списков Twitter доступны из конечной точки REST : http://cdn.syndication.twimg.com/widgets/timelines/widget ID. После успешного выполнения вызова REST переменная body этой анонимной функции будет содержать необходимую ленту публикаций Twitter.

На следующих трех этапах вы продолжите создание кода для сценария интерпретации index.js, объединив все необходимые компоненты на Шаге 6.

Шаг 4. Внесите исправления в ленту сообщений

Ответ на вызов REST имеет правильный формат JSON, но представлен в виде обычного текста, и для его преобразования в объект JSON мы воспользуемся встроенным в Node синтаксическим анализатором JSON. Наш сценарий также должен внести следующие изменения в атрибут bodyэтого объекта, чтобы его можно было подвергнуть интерпретации с помощью XML-анализатора node-elementtree :

  • Удалить все символы новой строки или возврата каретки, используя регулярные выражения \r и \n.
  • Преобразовать все экземпляры нескольких пространств в единое пространство, используя регулярное выражение \s.
  • Удалить теги <img> (они закрываются корректно в HTML, но не в XML).
  • Удалить из тегов pubdate пустой атрибут <time> (допустимый в HTML, но не в XML).
  • Найти и удалить символы в кодировке Юникод, такие как &lrm; и &amp; используя регулярное выражение &.*?;

Для внесения этих изменений воспользуйтесь следующим кодом:

var json = JSON.parse(body);
var list = json.body.replace(/(\r\n|\n|\r)/gm, " ")
 		     .replace(/\s+/g, " ")
		     .replace(/<img.*?>/gi, "")
		     .replace(/pubdate/gi, "")
		     .replace(/&.*?;/gi, "");

Шаг 5. Интерпретируйте исправленную ленту и возвратите ее в формате RSS

Теперь лента публикаций имеет правильный формат XML, и ее можно интерпретировать с помощью модуля Node.js node-elementtree :

  1. Из командной строки установите node-elementtree и добавьте его в файл package.json:

    npm --save install elementtree

  2. Чтобы интерпретировать XML как дерево документов, добавьте в сценарий следующий код:
    var etree = et.parse(list);
  3. Лента RSS должна содержать как минимум следующие узлы:
    • title: заглавие ленты RSS
    • link: HTML-ссылка на веб-сайт, связанный с лентой
    • description: description: описание ленты
    Эта информация хранится в документе XML в следующем формате:
    <?xml version="1.0" encoding="UTF-8"?>
    <rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
       <channel>
          <title>RSS Feed Title</title>
          <link>RSS Feed Link</link>
          <description>RSS FEED</description>
       </channel>
    </rss>

    Чтобы извлечь эти значения из дерева документов, можно воспользоваться выражениями XPath :
    • Заглавие списка присутствует в узле по пути div/h1.
    • Чтобы сформировать URL-адрес списка, используйте URL-адрес своей страницы Twitter из атрибута href узла по пути div/h2/a, объединив его с путем /lists/ и именем списка.
    • Описание присутствует в узле по пути div/p
    Используя эти значения, начните создавать ленту RSS, которую возвратите в ответе:
    var et = require('elementtree');
    
    var title = etree.findtext('div/h1');
    var link = etree.find('div/h2/a').get("href");
    var description = etree.findtext('div/p');
    var rss = '<?xml version="1.0"?><rss version="2.0" ;
    rss += '<channel><title>' + title + '</title>';
    rss += '<link>' + link + '/lists/' + title + '</link>';
    rss += '<description>' + description + ' </description>';
    rss += "</channel></rss>";
  4. Твиты из ленты содержатся в HTML-списке <ol> в виде элементов списка <li> . Все элементы списка извлекаются в виде массива посредством вызова функции etree.findall() из пути div/div/ol/li.

    Мы используем каждый твит для создания нового элемента в поле rss . Согласно спецификации присутствующий в ленте элемент RSS должен содержать поле заглавия или поле описания; все остальные поля являются необязательными.

    Для добавления очередного нового элемента к строке RSS воспользуйтесь этим кодом:

    var tweets = etree.findall('div/div/ol/li');
    for (var counter = 0; counter < tweets.length; counter++) {
        
       var tweet = tweets[counter];
       var tweetTitle = tweet.findtext('div/p').trim();
       var author = tweet.findtext('div[@class="timeline-Tweet u-cf js-tweetIdInfo"]/' +
                        'div[@class="timeline-Tweet-author"]/' +
                        'div/a/span[@class="TweetAuthor-screenName Identity-screenName"]');
                                    
       var tweetPermalink = tweet.find('div/div[@class="timeline-Tweet-metadata"]/a')
                                 .get('href');
       var pubDate = Date.parse(tweet.find('div/div[@class="timeline-Tweet-metadata"]/a/time')
                                     .get('datetime'));
        
       rss += "<item>";
       rss += "<title>" + tweetTitle + "</title>";
       rss += "<pubDate>" + new Date(pubDate).toUTCString() + "</pubDate>";
       rss += "<guid>" + tweetPermalink + "</guid>";
       rss += "<link>" + tweetPermalink + "</link>";
       rss += "<description><![CDATA[  " + author + ": " + tweetTitle + "]]></description>";
       rss += "</item>";
        
    }

    В предыдущем фрагменте кода для создания каждого элемента используются следующие данные:

    • Для заглавия – текст твита из узла div/p
    • Для автора – дескриптор Twitter из последующего узла, выбранный с помощью следующего выражения XPath (разбейте код на две строки, чтобы он поместился на странице):
      div[@class="timeline-Tweet u-cf js-tweetIdInfo"]/div[@class="timeline-Tweet-author"]/
      div/a/span[@class="TweetAuthor-screenName Identity-screenName"]
    • Для ссылки и guid, URL-адрес твита в атрибуте href узла по пути div/div[@class="timeline-Tweet-metadata"]/a
    • Для описания – имя автора в сочетании с текстом твита
    Кроме того, поле pubdate лемента RSS должно быть представлено в формате RFC-822. Объект JavaScript Date может вернуть дату в таком формате после вызова метода toUTCString() . Чтобы получить количество миллисекунд, прошедших с 1 января 1970 года, мы передадим методу Date.parse() атрибут datetime узла по пути div/div[@class="timeline-Tweet-metadata"]/a/time. Затем создадим новый объект Date с этим значением и вызовем метод toUTCString() для получения корректного значения.

Правильность строки RSS можно проверить с помощью сервиса W3C Feed Validation Service.

Шаг 6. Возвратите RSS из маршрута Express

Теперь вы готовы сконфигурировать сервер Express, чтобы возвратить строку RSS после вызова веб-сервиса:

  1. Установите Express из командной строки:

    npm --save install express

  2. В начало файла index.js, 2. добавьте код для создания сервера Express:
    var express = require('express');
    app.set('port', process.env.PORT || 3000);
    http.createServer(app).listen(app.get('port'), function(){
        
        console.log('Express server listening on port ' + app.get('port'));
    
    });
    
    app.get('/', function(request, response) {
    
    });
  3. Далее следует вызов запроса к ленте виджета (созданный на этапе Шаг 3). После вызова запроса добавьте код корректировки ленты с этапа Шаг 4 и код интерпретации с этапа Шаг 5. И наконец, вызовите метод res.send(rss);, чтобы вернуть готовую ленту RSS пользователю.
  4. Из командной строки запустите сервер:

    node index.js

  5. Чтобы увидеть результат, откройте в браузере страницу с адресом http://localhost:3000/ . Ниже приведен снимок экрана с лентой на основе моего списка Writers, в том виде, в каком она отображается в Firefox:: Screenshot of RSS feed for Writers list
    Screenshot of RSS feed for Writers list

Сервер прослушивает запросы по пути, заданном для запросов по умолчанию (/). Этот путь можно настроить в вызове функции app.get .

Шаг 7. Выполните развертывание в Bluemix

  1. Войдите на портал Bluemix DevOps Services и создайте новый проект. Выберите создание нового репозитория Git, размещенного в Bluemix, а для остальных параметров используйте значения по умолчанию.
  2. Из командной строки ОС выполните клонирование репозитория в локальную систему:

    git clone --no-checkout https://hub.jazz.net/git/username/project name
    cd project name
    echo "# readme" >> README.md
    git add README.md
    git commit -m "first commit"
    git push -u origin master

  3. Скопируйте файл package.json и файл сценария index.js из локального каталога проектов Node.js в новый каталог проекта.
  4. Выполните фиксацию и помещение в репозиторий этих двух файлов из нового каталога.
  5. В проекте на портале Bluemix DevOps Services нажмите кнопку BUILD & DEPLOY (СКОМПОНОВАТЬ И РАЗВЕРНУТЬ) .
  6. Нажмите кнопку ADD STAGE (ДОБАВИТЬ ЭТАП) и выберите вкладку JOBS (ЗАДАНИЯ) .
  7. Нажмите кнопку ADD JOB (ДОБАВИТЬ ЗАДАНИЕ) и выберите Deploy (Развернуть) . Убедитесь, что значения Organization и Space заданы верно, и нажмите кнопку SAVE (СОХРАНИТЬ) .
  8. После внесения изменений нажмите кнопку RUN STAGE (ЗАПУСТИТЬ ЭТАП) чтобы выполнить развертывание в Bluemix.
  9. После развертывания откройте ссылку URL на приложение Bluemix, чтобы увидеть новую ленту RSS.

Заключение

В данном руководстве описывается процесс создания канала RSS путем интерпретации выходных данных из виджета списка Twitter и объясняется, как сделать этот канал доступным онлайн посредством развертывания в Bluemix. Вот несколько предложений по дальнейшей разработке:

  • Написанный вами сценарий может читать данные только из того виджета, который вы создали. Измените вызов запроса и маршрут Express таким образом, чтобы вы могли передавать в качестве параметра ID виджета для чтения ленты любого виджета.
  • Формат ретвитов несколько отличается от формата обычных твитов, поэтому для извлечения корректных значений имени автора, даты публикации и текста твита потребуются другие селекторы XPath. Чтобы получить корректные значения для этих атрибутов, изучите ленту целиком в инструменте просмотра XML.
  • Для всех модулей Node.js доступны разные варианты. Оцените, какие изменения потребуется внести для создания ленты RSS с помощью других модулей.
  • Формат RSS предусматривает ряд необязательных элементов, которые вы могли бы включить в ленту. Изучите спецификацию и разберитесь, как включить их, используя узлы из ленты виджета.
  • Рекомендуется (хотя это и не обязательно) включить в ленту RSS элемент atom:link с атрибутом href, содержащим URL-адрес ленты. Добавьте этот элемент к коду, задав для него в качестве значения адрес развернутого в Bluemix кода.
  • Текст твита в ленте RSS сокращается за счет использования ссылки или хэш-тега. Разберитесь, как включать текст из ссылок и хэш-тегов в поле описания узла элемента RSS

Ресурсы для скачивания


Похожие темы


Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Web-архитектура, Облачные вычисления
ArticleID=1034887
ArticleTitle=Преобразование списков Twitter в ленту RSS
publish-date=07132016