новостная лента
Сбор новостных статей через каналы RSS / Atom с использованием Python
Или как перестать зависеть от поставщиков данных
В одном из своих предыдущих постов я говорил о том, как можно очищать и анализировать новостные статьи с помощью всего 5 строк кода:
На этот раз я покажу вам, как можно настроить канал для автоматического сбора всех новых статей, опубликованных практически любым поставщиком новостей (например, NY Times, CNN, Bloomberg и т. Д.)
Для достижения этой цели я покажу вам, как можно автоматизировать сбор новостей с помощью пакета Python feedparser, который помогает нормализовать каналы RSS / Atom.
Для кого эта статья?
Для инженеров и специалистов по обработке данных, которые могут захотеть собрать свои собственные данные и попрактиковаться в построении каналов данных.
Что такое RSS и Atom?
RSS - это обычный текст в формате XML, содержащий краткое изложение статей, недавно опубликованных некоторыми поставщиками контента (новости, подкасты, личный блог и т. Д.)
Наиболее распространенными производителями RSS являются издатели новостей.
RSS-канал существует для обеспечения доступа к последним новостям (например, для агрегаторов новостей и синдикаторов новостей).
RSS-канал не содержит всего текста статьи (в большинстве случаев), но предоставляет некоторую базовую информацию, такую как автор, название, описание, время публикации и т. Д.
Atom - это еще один формат XML, который был разработан как альтернатива RSS-каналу. Atom кажется более продвинутым по сравнению с RSS, но я не собираюсь сравнивать эти 2 формата в этом посте.
Пример RSS XML:
<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0"> <channel> <title>RSS Title</title> <description>This is an example of an RSS feed</description> <link>http://www.example.com/main.html</link> <lastBuildDate>Mon, 06 Sep 2010 00:01:00 +0000 </lastBuildDate> <pubDate>Sun, 06 Sep 2009 16:20:00 +0000</pubDate> <ttl>1800</ttl> <item> <title>Example entry</title> <description>Here is some text containing an interesting description.</description> <link>http://www.example.com/blog/post/1</link> <guid isPermaLink="false">7bd204c6-1655-4c27-aeee-53f933c5395f</guid> <pubDate>Sun, 06 Sep 2009 16:20:00 +0000</pubDate> </item> </channel> </rss>
Очистите новости через конечную точку RSS
Итак, осталось только собрать все URL-адреса (конечные точки) издателей новостей, которые нас интересуют.
В этой статье я использую конечную точку канала NY Times. Для этого мне пришлось:
- перейдите на https://www.nytimes.com/
- «Проверить» исходный код страницы
- поиск по запросу "rss"
- получить первый результат
Давайте возьмем эту ссылку и проверим, похожа ли она на то, что нам нужно.
Хорошо, как мы видим, это RSS «Нью-Йорк Таймс».
В разделе ‹channel› вы можете найти общую информацию о самом фиде - описание, время создания, язык и т. Д.
Каждый ‹item› в этом RSS представляет статью. Первый пункт представляет собой статью с заголовком (‹title›) под названием «Трамп делает ставку, что он может изолировать Иран и очаровать Северную Корею». Это не так просто ».
Если мы перейдем по ссылке (‹link›) под этим ‹item›, мы будем перенаправлены на исходную страницу статьи:
RSS не предоставит нам полный текст статьи, но вместо этого предложит краткое ‹description›.
Feedparser
Теперь, когда мы знаем, что такое RSS и как мы можем его использовать, мы можем попытаться автоматизировать способ получения новых статей.
Главный недостаток RSS / Atom-каналов в том, что они не нормализованы. Согласно странице Википедии, в RSS / Atom есть только несколько обязательных полей (ссылка, заголовок, описание).
Это означает, что в случае, если вы хотите хранить данные от разных издателей новостей, вы должны либо учитывать все возможные пары ключ-значение, либо использовать некоторую технологию без схемы (например, elasticsearch).
Изучите пакет feedparser
pip install feedparser
import feedparser
feed = feedparser.parse('https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml')
Теперь наш канал загружается под переменной feed
. Под атрибутом .feed
мы можем найти основную информацию о самих метаданных канала.
feed.feed Out[171]: {‘title’: ‘NYT > Top Stories’, ‘title_detail’: {‘type’: ‘text/plain’, ‘language’: None, ‘base’: ‘https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml', ‘value’: ‘NYT > Top Stories’}, ‘links’: [{‘rel’: ‘alternate’, ‘type’: ‘text/html’, ‘href’: ‘https://www.nytimes.com?emc=rss&partner=rss'}, {‘href’: ‘https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml', ‘rel’: ‘self’, ‘type’: ‘application/rss+xml’}], ‘link’: ‘https://www.nytimes.com?emc=rss&partner=rss', ‘subtitle’: ‘’, ‘subtitle_detail’: {‘type’: ‘text/html’, ‘language’: None, ‘base’: ‘https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml', ‘value’: ‘’}, ‘language’: ‘en-us’, ‘rights’: ‘Copyright 2020 The New York Times Company’, ‘rights_detail’: {‘type’: ‘text/plain’, ‘language’: None, ‘base’: ‘https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml', ‘value’: ‘Copyright 2020 The New York Times Company’}, ‘updated’: ‘Thu, 02 Jan 2020 15:03:52 +0000’, ‘updated_parsed’: time.struct_time(tm_year=2020, tm_mon=1, tm_mday=2, tm_hour=15, tm_min=3, tm_sec=52, tm_wday=3, tm_yday=2, tm_isdst=0), ‘published’: ‘Thu, 02 Jan 2020 15:03:52 +0000’, ‘published_parsed’: time.struct_time(tm_year=2020, tm_mon=1, tm_mday=2, tm_hour=15, tm_min=3, tm_sec=52, tm_wday=3, tm_yday=2, tm_isdst=0), ‘image’: {‘title’: ‘NYT > Top Stories’, ‘title_detail’: {‘type’: ‘text/plain’, ‘language’: None, ‘base’: ‘https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml', ‘value’: ‘NYT > Top Stories’}, ‘href’: ‘https://static01.nyt.com/images/misc/NYT_logo_rss_250x40.png', ‘links’: [{‘rel’: ‘alternate’, ‘type’: ‘text/html’, ‘href’: ‘https://www.nytimes.com?emc=rss&partner=rss'}], ‘link’: ‘https://www.nytimes.com?emc=rss&partner=rss'}}
Наиболее важные поля - copyright
и published
.
Feedparser присваивает этим атрибутам правильные значения, чтобы вам не приходилось тратить время на их нормализацию самостоятельно.
Нормализованные статьи
Как и в случае с фидами, вы можете найти информацию о каждой статье под атрибутом .entries
.
feed.entries[0].title Out[5]: 'Trump Bet He Could Isolate Iran and Charm North Korea. It’s Not That Easy.'
Таким образом, мы будем знать основную информацию о каждом элементе фида.
Если вам нужен полный текст статьи, вам нужно взять URL-адрес и использовать газету3k. Отметьте другую мою статью, которую я встроил в начало этого поста.
Дальнейшая работа
Попытайтесь подумать о том, как вы могли бы построить канал данных для сбора новых статей, дедупликации с теми, которые ваша база данных уже видела. Кроме того, дополнительный конвейер NLP сверху может дать много полезных идей (пакет python spaCy идеально подходит для этого).
В своем личном блоге я рассказываю о том, как я создаю новостную рассылку - API для доступа к новостным данным от самых популярных новостных издателей. Если вы хотите узнать, как масштабировать то, что я описал выше, до тысяч каналов, подпишитесь на мой Средний блог и настройтесь на мой Твиттер.