Время прочтения: 5 мин.

Для начала разберемся как она работает на примере одного сайта с новостями. Выгрузим все статьи с сайта http://www.ted.com

import newspaper
from newspaper import Article
def grab(url):
cbr_paper = newspaper.build(url ,memoize_articles=False)
papers = []
urls_set = set()
for article in cbr_paper.articles:
  		if article.url not in urls_set:
    			urls_set.add(article.url)
    	 	if not str(article.url).endswith('#commentaires'):
        			papers.append(article.url)
return cbr_paper 


grab('http://www.ted.com')
print(len(papers))
out: 187

В результате выполнения в переменную papers сохраняются url адреса 187 статей. Это те новости, на сайте которые имеют пометку актуальные. При постоянном использовании данной библиотеке чтобы не обрабатывать отдельно дубли новостей можно в атрибуте memoize_articles поставить True и тогда будут выгружаться только свежие новости.

print(papers)
out:
['http://www.ted.com/talks/priscilla_chomba_kinywa_a_free_and_fair_internet_benefits_everyone', 'http://www.ted.com/talks/matt_walker_4_ways_the_covid_19_pandemic_changed_the_way_we_sleep', 'http://www.ted.com/talks/jamil_zaki_how_to_escape_the_cynicism_trap'
…
'http://www.ted.com/talks/fabio_pacucci_yes_scientists_are_actually_building_an_elevator_to_space', 'http://www.ted.com/talks/maria_van_kerkhove_how_to_end_the_pandemic_and_prepare_for_the_next', 'http://www.ted.com/talks/sister_true_dedication_3_questions_to_build_resilience_and_change_the_world', 'http://www.ted.com/talks/dawn_lippert_community_investment_is_the_missing_piece_of_climate_action']

На портале NTA неоднократно разбиралась библиотека для парсинга beautifulsoup, она дает возможность более детально проанализировать контент той или иной странички, но в нашей задаче нам больше подойдет библиотека «Newspaper3k», которая заточена под сбор исключительно новостных постов в большой массив данных.

Для дальнейшей работы с новостями нам необходимо сохранить текст самих новостей:

Для дальнейшей работы с новостями нам необходимо сохранить текст самих новостей:
def textgrab(paper_def):
texts = []
for i in paper_def.articles:
i.download()
try: 
i.parse()
except Exception:
pass
texts.append(i.text)
return(texts)

textgrab(cbr_paper)
print(texts)
out:
["You have JavaScript disabled\n\nFor the best experience, please turn JavaScript on. Here's how", "You have JavaScript disabled\n\nFor the best experience, please turn JavaScript on. Here's how", "You have JavaScript disabled\n\nFor the best experience, please turn JavaScript on. Here's how", "You have JavaScript disabled\n\nFor the best experience, please turn JavaScript on. Here's how", "You have JavaScript disabled\n\nFor the best experience, please turn JavaScript on. Here's how", 
...
JavaScript on. Here's how", "You have JavaScript disabled\n\nFor the best experience, please turn JavaScript on. Here's how", "You have JavaScript disabled\n\nFor the best experience, please turn JavaScript on. Here's how", "You have JavaScript disabled\n\nFor the best experience, please turn JavaScript on. Here's how"]

По мимо параметра article.text из статей можно получить:

article.authors #Автора

article.publish_date #Дату публикации

article.top_image #Главную картинку

article.movies #Ссылки на видео

С данными инструментами можно, например, нарисовать облако тегов из ключевых слов в статьях:

from wordcloud import WordCloud
import matplotlib.pyplot as plt
texts = ' '.join(texts)
cloud = WordCloud().generate(texts)
plt.imshow(cloud)
plt.axis('off')

Также можно составить статистику по авторам статей или по количеству публикаций за определенный период.

Теперь, когда мы разобрались с принципом работы библиотеки на примере одного портала, можно переходить к решению нашей задачи, сбора новостей с популярных таблоидов.

newspaper.hot()
newspaper.popular_urls()
out: 
['http://www.huffingtonpost.com',
 'http://cnn.com',
 'http://www.time.com',
 'http://www.ted.com',
 'http://pandodaily.com',
...
 'http://www.parade.com',
 'http://www.bbcamerica.com',
 'http://washingtonindependent.com',
 'http://drudgereport.com',
 'http://beta.na.leagueoflegends.com']

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

Добавляем список популярных новостных лент в параметры функций, описанных выше

hot= newspaper.popular_urls()
for i in hot:
print(textgrab(grab(i)))
print(len(papers))

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

[['NORTHBOROUGH — A Worcester woman whose gun fired while at a Walmart self-checkout station with her toddler is facing an added charge of reckless child endangerment, according to police.\n\nCrystaly Perez, 31, told investigators she was looking through her purse to pay for groceries when her 9 mm pistol discharged, police said.
….
 development includes the creation of Spruce Street, which in Boston Capital\'s plans runs one-way from Washington Street to Green Street. The $1.25 million is the estimated cost of the Spruce Street portion of the project.', '']]

Далее в рамках анализа массива информации, можно осуществить поиск любой информации и репрезентовать данные в нужном ключе. Например, возьмем список топ 100 российских изданий и попробуем определить индекс цитируемости. Для примера реализовать его можно на простом примере – количество упоминания.

rus_news_urls = ['https://russian.rt.com',
'http://life.ru',
'http://www.rbc.ru/',
'http://www.vedomosti.ru/',
'https://www.gazeta.ru/',
…
'http://1tmn.ru/',
'https://kazanfirst.ru/',
'http://u-f.ru/']

all_texts = []
for i in rus_news_urls:
all_texts.append(textgrab(grab(i)))

cnt = 0
for i in len(all_texts):
cnt = cnt + len(all_texts[i])
print(cnt)
out: 8293

Всего в массив сохранилось 8293 новости

import re
nword = 'доллар'
newscount=0
mediacount=0
cn = 0
for i in all_texts:
mediacount=mediacount+1
    	for ir in i:
        		nraz = len(re.findall(nword, ir))
        		if nraz > 0:
            			newscount = newscount+1
for i in all_texts:
cn = cn+len(i)

print("Искомый объект найден в " + str(mediacount) + " изданиях, в " + str(newscount) +" новостях, всего новостей проанализировано " + str(cn) )
out:  Искомый объект найден в 2 изданиях, в 57 новостях, всего новостей проанализировано 677

Можно выделить новости по определенной тематике в отдельный массив, для углубленного анализа. Используя функцию article.nlp(), благодаря ей библиотека для каждой новости выберет ключевые слова и уже относительно их можно ранжировать новости.

import nltk
nltk.download('punkt')
article = cbr_paper.articles[0]
article.nlp()
keywords = article.keywords
print(keywords)
out: ['unthinkable', 'war', 'order', 'vital', 'means', 'conversation', 'world', 'global', 'tedcommembership', 'visit', 'ted', 'ukraine']

Также можно проанализировать тональности или эмоциональной окраски новости или ее ключевых слов.

from textblob import TextBlob
polar = TextBlob(texts).sentiment
print(polar)
out: Sentiment(polarity=0.13000416909387866, subjectivity=0.4770714336479513)

Проведя подобный анализ для всех новостей можно сделать вывод о общем позитивном или негативном окрасе новостного фона.

В дальнейшем полученный массив данных со всех новостных сайтов можно использовать для любых целей аудита: применение Text-mining, определения индекса цитируемости, сбора новостей о интересующем объекте, для определения эмоциональной окраски текста и мн. др. Также данную библиотеку можно адаптировать под более узконаправленные задачи, связанные с изучением какого-то конкретного сайта.