Как извлечь URL фида из файла OPML, экспортированного из Google Reader?

У меня есть программа под названием Rss-Aware, которую я пытаюсь использовать. В основном это программа проверки каналов на рабочем столе, которая проверяет, обновляются ли RSS-каналы, и выдает уведомление через систему Notify-OSD Ubuntu.

Однако, чтобы узнать, какие каналы следует проверять, вы должны перечислить URL-адреса каналов в текстовом файле в ~/.rss-aware/rssfeeds.txt один за другим в списке с разрывом строки между URL-адресами каналов. Что-то вроде:

http://example.com/feed.xml
http://othersite.org/feed.xml
http://othergreatsite.net/rss.xml

... кажется довольно простым, верно? Ну, список фидов, которые я хотел бы использовать, экспортируется из Google Reader в виде файла OPML (это тип XML), и я понятия не имею, как его проанализировать, чтобы просто выводить URL фидов. Кажется, это должно быть довольно просто, но я в тупике.

Я хотел бы, чтобы кто-нибудь мог дать реализацию на Python или Ruby или что-то, что я мог бы быстро сделать из подсказки. Скрипт bash был бы потрясающим.

Большое спасибо за помощь, я очень слабый программист и хотел бы узнать, как выполнять этот базовый анализ.

РЕДАКТИРОВАТЬ: Кроме того, вот файл OPML, из которого я пытаюсь извлечь URL канала.

5 ответов

Я написал парсер списка подписки для этой цели. Он называется listparser и написан на Python. Я только что проверил ваш файл OPML, и он, кажется, отлично разбирает файл. Это также сделает ярлыки ваших каналов доступными.

Если вы когда-либо использовали feedparser, интерфейс должен быть знаком:

>>> import listparser as lp
>>> d = lp.parse('https://dl.dropbox.com/u/670189/google-reader-subscriptions.xml')
>>> len(d.feeds)
112
>>> d.feeds[100].url
u'http://longreads.com/rss'
>>> d.feeds[100].tags
[u'reading']

Можно создать файл с URL-адресами фида, используя скрипт, подобный следующему:

import listparser as lp
d = lp.parse('https://dl.dropbox.com/u/670189/google-reader-subscriptions.xml')
f = open('/home/USERNAME/.rss-aware/rssfeeds.txt', 'w')
for i in d.feeds:
    f.write(i.url + '\n')
f.close()

Просто замени USERNAME с вашим настоящим именем пользователя. Готово!

Синтаксический анализ XML был настолько прост в реализации и отлично работал для меня.

from xml.etree import ElementTree
def extract_rss_urls_from_opml(filename):
    urls = []
    with open(filename, 'rt') as f:
        tree = ElementTree.parse(f)
    for node in tree.findall('.//outline'):
        url = node.attrib.get('xmlUrl')
        if url:
            urls.append(url)
    return urls
urls = extract_rss_urls_from_opml('your_file')

Поскольку это файл XML, вы можете использовать запрос XPath для извлечения URL-адресов. В файле XML похоже, что URL-адреса RSS-канала хранятся в xmlUrl атрибутов. Выражение XPath //@xmlUrl выберет все значения этого атрибута.

Если вы хотите проверить это в своем веб-браузере, вы можете использовать онлайн-тестер XPath. Если вы хотите выполнить этот запрос XPath в Python, этот вопрос объясняет, как использовать XPath в Python. Кроме того, в документации по lxml есть страница об использовании XPath в lxml, которая может оказаться полезной.

Вы также можете использовать регулярные выражения. Я использовал следующее регулярное выражение поиска и замены для преобразования моего экспорта Google Reader OPML в импорт Live-закладок Firefox HTML:

^\s+<outline.*?title="(.*?)".*?xmlUrl="(.*?)".*?htmlUrl="(.*?)".*?/>
<DT><A FEEDURL="$2" HREF="$3">$1</A>

Есть несколько пакетов Python, которые могут помочь, это действительно старый (как и сам этот вопрос) и, вероятно, больше не поддерживаемый (я даже не могу найти исходный код), но его довольно просто использовать. В качестве однострочника Python (помещая весь код Python в командную строку):

      $ pip install opml
$ python3 -c 'import opml; o=opml.parse("stitcher.opml"); print(*[x.xmlUrl for x in o], sep="\n")'

Это распечатывает один URL-адрес в строке из файла OPML. Альтернативно просто изменитезаявление по желанию. Поскольку пакет Python кроме этого не особо полезен, я бы удалил его после того, как вы закончите:(См.: https://pypi.org/project/opml/ )

Другие вопросы по тегам