Конкурс инструкций

Создаем простой поисковый сервис статей с упоминаниями указанных в запросе персон

Перед группой программистов была поставлена задача создать сервис для накопления информации об упоминании публичных персон в новостных интернет-порталах (далее сервис):

Что должен видеть пользователь сервиса: интернет ресурс, на котором можно запустить «Просмотр общей статистики».

В результате запуска отображается информация в виде таблицы с полями: «Имя персоны», «Количество упоминаний», «Название статей, Даты статьи».

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

Также пользователь может запустить просмотр /поиск статистики по конкретной персоне.

Таким образом, если информация по запросу на поиск пользователя уже имеется в базе данных, то ответ будет сформирован сразу и выведен в составе «Просмотра общей статистики», если же информация по запросу в базе данных отсутствует, то будет сформировано задание для crawler, обработанная информация с которого будет занесена в базу данных, откуда и будет сформирован ответ пользователю.

Crawler (обходчик) — служба, которая по определенному расписанию, или принудительно, обращается к сайтам в интернете. Анализирует их на наличие новых страниц. Загружает новые страницы, после чего обрабатывает контент новой страницы. Результаты обработки и ссылку на новую страницу записывает в Базу Данных. Результатом обработки является количество упоминаний имен политиков на странице сайта.

Наша группа разделилась на 2 большие подгруппы:

  • программирование сервиса на Java;
  • программирование сервиса на Python.

Далее внутри групп было произведено деление по программированию компонент.

Группе, в которую попал и я, была поручена разработка crawler на Python и пробный новостной сайт «lenta.ru».

Для поиска данных на html страницах web сайтов можно использовать различные библиотеки Python, например: Scrapy, Selenium, Beautiful Soup.

Scrapy — это готовая платформа для поиска данных с веб-сайтов, которая работает без блокировки отправленных запросов, самая быстрая и надежная, особенно при создании сложных проектов.

Selenium используется для тестирования веб-приложений.

Beautiful Soup — быстро извлекает данные из скачанных (локальных или в память компьютера) файлов HTML и XML.

Выбрана была библиотека Beautiful Soup вследствие не высокой сложности нашего проекта.

Установим Beautiful Soup на компьютер:

pip3 install bs4 - для Windows; sudo pip3 install bs4 – для Ubuntu, Centos.

В отличии от Scrappy, Beautiful Soup не может напрямую просматривать страницы Web сайтов, поэтому еще необходимо поставить библиотеку requests, которая работает с http – запросами:

pip3 install requests - для Windows; sudo pip3 install requests – для Ubuntu, Centos.

По заданию на вход crawler должны быть поданы следующие параметры: персона, дата статей, на выходе название статей, количество упоминаний персоны. По входным и выходным данным в базу будут произведены записи: дата найденных статей, персона, название статей, количество упоминаний персоны.

Разделим наше задание на несколько этапов:

  1. Определение страниц/разделов в lenta.ru, в которых будет производится поиск статей;
  2. Открытие указанных страниц/разделов в lenta.ru за конкретную дату;
  3. Получение данных с указанных страниц/разделов в lenta.r; Формализация данных поиска (персоны и даты);
  4. Поиск персоны в статьях с указанных страниц/разделов в lenta.ru за конкретную дату;
  5. Передача данных в базу данных сервиса в json — формате {‘гиперссылка на статью’: Количество упоминаний}.

Определение страниц/разделов в lenta.ru, в которых будет производится поиск статей

Любой серьезный сайт публикует карту своего сайта в файле robots.txt, для того чтобы было видно куда разрешено роботам спокойно заходить и смотреть страницы и/или указать файл карты сайта. Обычно это sitemap.xml или sitemap.xml.gz

У новостного сайта lenta.ru карта сайта описана в файле https://lenta.ru/sitemap.xml.gz

Проведя анализ данного файла, был сделан вывод: основные папки статей: news, articles.

Открытие указанных страниц/разделов в lenta.ru за конкретную дату

Пример кода открытия страницы с помощью requests:

import requests year = “2018” may = “06” day = “28” main_url = 'https://lenta.ru' them = 'news' url = "%s/%s/%s/%s/%s/" % (main_url, them, year, may, day) r = requests.get(url) page = r.text print(page)

(в блоках добавлена функция print (), чтобы можно было увидеть результат работы кода)

Так как страниц/разделов может быть несколько, немного модифицируем наш код (этот код используйте только в составе класса[1])

import requests year = “2018” may = “06” day = “28” main_url = 'https://lenta.ru' thems = ('news', 'articles') for them in thems: url = "%s/%s/%s/%s/%s/" % (main_url, them, year, may, day) r = requests.get(url) page = r.text print(page)

Получение данных с указанных страниц/разделов в lenta.ru

Для получения данных о статьях необходимо определить в каких тегах они закреплены.

Проведя анализ полученной страницы, можно сделать вывод:

— статьи на этой странице ограничены тегами:

div class=”row”; div class=”titles”.

На основании этих ограничений прочитаем выгруженную страницу с помощью Beautyful Soup и сохраним все гиперссылки на статьи в список.

import requests from bs4 import BeautifulSoup #…….. здесь предыдущий код newlinks = [] soup = BeautifulSoup(page, 'lxml') link_block = soup.find_all('div', class_='row') for blocks in link_block: if blocks.find_all('div', class_='titles'): for block in blocks.find_all('div', class_='titles'): newlinks.append("%s%s" % (main_url, block.find('a').get('href'))) print(newlinks)

Так выглядит список статей:

Формализация данных поиска (персоны и даты)

У нас есть список статей и осталось провести поиск искомой персоны. Имеется немало разных библиотек, с помощью которых можно задать правильный поиск по Фамилии Имени Отчеству.

Немного упростим задачу, будем искать только по фамилии персоны, для этого напишем следующий код:

name = 'Меркель' if (name[-2:] == 'ая' or name[-2:] == 'яя' or name[-2:] == 'ий' or name[-2:] == 'ой' \ or name[-2:] == 'ый' or name[-2:] == 'ая') and len(name) > 4: newname = name[:-2] elif name[-1:] == 'а' or name[-1:] == 'ь' or name[-1:] == 'й' and len(name) > 4: newname = name[:-1] else: newname = name print(newname)

Если вы заметили, то дата в коде написана в виде

url = "%s/%s/%s/%s/%s/" % (main_url, them, year, may, day)..

То есть необходимо распарсить входящую дату, что будет сделано с помощью кода:

date = "26.06.2018" year = date.split(".")[2] may = date.split(".")[1] day = date.split(".")[0]

И необходимо вставить эти 2 фрагмента кода выше блока «Открытие указанных страниц/разделов в lenta.ru за конкретную дату».

Поиск персоны в статьях с указанных страниц/разделов в lenta.ru за конкретную дату

С помощью requests открываем статьи, указанные в списке newlinks, будем искать и считать количество упоминаний нашей персоны в каждой статье с помощью Beautyful Soup.

pages_name ={} for url in newlinks: page = requests.get(url) soup = BeautifulSoup(page.text, 'lxml') link_block = soup.find_all('div', class_='b-topic__content') page_count = str(link_block).count(newname) if page_count > 0: pages_name[url] = page_count print(pages_name)

Передача данных в базу данных сервиса в json — формате {‘гиперссылка на статью’: Количество упоминаний}

На выходе:

{‘https://lenta.ru/articles/2018/06/25/merkel_i_ee_problemi/’: 21}

Была найдена 1 статья с 21 упоминанием персоны Меркель.

Вот и всё. Как видите ничего сложного. Весь указанный код, объединенный в класс, выложен на https://github.com/IldarVS/crawler

0
3 комментария
Andrew Solovov

Посмотрите ещё в сторону https://natasha.github.io/
Отличный инструмент для извлечения структурированной информации.
Можно обучать под свои требования

Ответить
Развернуть ветку
NTA
Автор

Спасибо вам за совет! 

Ответить
Развернуть ветку
Борис Васильев

Я, конечно, ничего не понял в материале.
Но вот лет ...дцать назад, тогдашняя Госсекретарь США попросила важного министра РФ дать ей посмотреть-послушать материалы радио и ТВ о её персоне (тогда интернет не был так развит, как сейчас).
Министерство оказалось в шоке, не знало, с чего начать.

На мою беду и их радость, я забрёл к нач. департамента "на огонёк".
Получил между ушей вопрос=задание.
Через разумные месяцы и деньги, всё выполнили, к общему удовольствию:
- мониторинг всего и вся;
- выжимки и видео-аудио записи.
Подробнее на https://proza.ru/2015/07/13/393
Как помочь МИДу и Госсекретарю США.

Ответить
Развернуть ветку
Читать все 3 комментария
null