[Из песочницы] API Медузы: пишем полнотекстовый RSS
Как и многих других, кто использует RSS, меня напрягают фиды, которые возвращают новость не целиком, а лишь краткую версию. В таком случае нет возможности читать фид в офлайне.Meduza.io — не исключение: текст приходит урезанный, приходится каждый раз переходить из ридера в браузер для прочтения одной новости. Особенно это выглядело ужасным, когда на Медузе не было нормальной мобильной версии, веб-версия на телефоне сильно тормозила.
Существуют различные сервисы для парсинга html в rss, но когда я наткнулся на консольный клиент для Медузы, у меня сразу же возник вопрос, а какое API там используется и можно ли его заюзать для написания своего приложения?
Далеко ходить не пришлось, код консольного приложения выложен на гитхабе и представляет собой js-ку, которая обращается к искомому API.Получение списка новостей https://meduza.io/api/v3/search? chrono=news&page=0&per_page=10&locale=ruchrono — принимает значения news, cards, articles, shapito или polygon, в зависимости от рубрики, которую хотим получить; page — номер страницы; per_page — количество записей на странице; locale — локаль ru или en; Получение отдельной новости https://meduza.io/api/v3/shapito/2015/06/02/vyshel-neofitsialnyy-terminalnyy-klient-meduzyТут просто подставляется url, полученный из прошлого пункта. Взять исходный фид rss по адресу https://meduza.io/rss/all, но вместо урезанных новостей подставлять текст новости, полученный через API. Я взял руби и написал немного кода для парсинга исходного rss фида: Nokogiri: XML (open ('https://meduza.io/rss/all')) А также код, который парсит json отдельно взятой новости: JSON: parse (open ('https://meduza.io/api/v3/' + post_url).read)['root']['content']['body'] Подставляем одно в другое и получаем нечто следующее:
require 'open-uri' require 'json' require 'nokogiri'
$meduza = 'https://meduza.io' $meduza_rss = $meduza + '/rss/%s' $meduza_api = $meduza + '/api/v3/%s'
class Meduza def Meduza.generate (feed = 'all') doc = Nokogiri: XML (open ($meduza_rss % feed)) doc.xpath ('/rss/channel/item').each do |item| post_id = item.xpath ('link').inner_text.gsub (/^#{$meduza}\//, '') json = JSON: parse (open ($meduza_api % post_id).read) item.search ('description').each do |description| description.content = json['root']['content']['body'].gsub ('src=»/image/', 'src=»//meduza.io/image/') end end doc.to_xml end end
puts Meduza.generate Попутно меняем относительные url картинок на абсолютные с помощью метода gsub. Написано минималистичное приложение на sinatra, которое можно развернуть, например, на хостинге heroku и пользоваться на здоровье (и к тому же совершенно бесплатно). Избавиться от «засыпания» приложений на heroku поможет сервис вроде этого.Исходный код приложения выложен на github, спасибо за внимание!
P.S. Ссылка на работающее приложение meduza.herokuapp.com/rss (до тех пор, пока бесплатный аккаунт heroku сможет выдержать нагрузку).