Как и многих других, кто использует RSS, меня напрягают фиды, которые возвращают новость не целиком, а лишь краткую версию. В таком случае нет возможности читать фид в офлайне.
Meduza.io — не исключение: текст приходит урезанный, приходится каждый раз переходить из ридера в браузер для прочтения одной новости. Особенно это выглядело ужасным, когда на Медузе не было нормальной мобильной версии, веб-версия на телефоне сильно тормозила.
Существуют различные сервисы для парсинга html в rss, но когда я наткнулся на консольный клиент для Медузы, у меня сразу же возник вопрос, а какое API там используется и можно ли его заюзать для написания своего приложения?
Далеко ходить не пришлось, код консольного приложения выложен на гитхабе и представляет собой js-ку, которая обращается к искомому API.
https://meduza.io/api/v3/search?chrono=news&page=0&per_page=10&locale=ru
chrono — принимает значения 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 фида:
А также код, который парсит json отдельно взятой новости:
Подставляем одно в другое и получаем нечто следующее:
Попутно меняем относительные url картинок на абсолютные с помощью метода gsub.
Написано минималистичное приложение на sinatra, которое можно развернуть, например, на хостинге heroku и пользоваться на здоровье (и к тому же совершенно бесплатно). Избавиться от «засыпания» приложений на heroku поможет сервис вроде этого.
Исходный код приложения выложен на github, спасибо за внимание!
P. S. Ссылка на работающее приложение meduza.herokuapp.com/rss (до тех пор, пока бесплатный аккаунт heroku сможет выдержать нагрузку).
Meduza.io — не исключение: текст приходит урезанный, приходится каждый раз переходить из ридера в браузер для прочтения одной новости. Особенно это выглядело ужасным, когда на Медузе не было нормальной мобильной версии, веб-версия на телефоне сильно тормозила.
Существуют различные сервисы для парсинга html в rss, но когда я наткнулся на консольный клиент для Медузы, у меня сразу же возник вопрос, а какое API там используется и можно ли его заюзать для написания своего приложения?
API
Далеко ходить не пришлось, код консольного приложения выложен на гитхабе и представляет собой js-ку, которая обращается к искомому API.
Получение списка новостей
https://meduza.io/api/v3/search?chrono=news&page=0&per_page=10&locale=ru
chrono — принимает значения 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 сможет выдержать нагрузку).
samat
Кажется хабр как коммьюнити и срачи в комментах умерло уже давно, но если что — техдир медузы в чяте.