python

Мелкая питонячая радость #11: реактивное программирование, парсинг страниц и публикация моделей маши

  • пятница, 23 октября 2020 г. в 00:32:17
https://habr.com/ru/post/523878/
  • Python


image


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


RxPy


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


Допустим, у вас есть коллекция ActiveRecord записей из СУБД. Вам нужно найти в этой коллекции определенные записи с определенными свойствами и применять к ним набор операций — что-то пересчитать, что-то после этого обновить в базе. В терминах rx вы бы сперва сформировали итератор/массив с первоначальным результатом запросов в базу, а потом бы описали пайплайн для прохождения записей чере все последующие шаги обработки.


В python из коробки реактивное программирование не поддерживается, для реализации этой концепции есть внешняя библитека rxpy.


Рассмотрим пример работы с JSON, в котором мы строим пайплайн из двух шагов и обрабатываем множество записей одним потоком.


import requests
import rx
import json
from rx import operators as ops

# Достаем JSON данные
content = requests.get('https://jsonplaceholder.typicode.com/users')
y = json.loads(content.text)

# Превращаем dict в специальную коллекцию для работы в rxpy
source = rx.from_(y)

# Эта функция будет принимать участие в нашем пайплайне
def filternames(x):
   if (x["name"].startswith("C")):
      return x["name"]
   else :
      return ""

#  Собираем пайплайн в два шага — фильтрация коллекции и обработка значений
case1 = source.pipe(
   ops.filter(lambda c: filternames(c)),
   ops.map(lambda a:a["name"])
)

# Вешаем обработчики на события пайплайна
case1.subscribe(
   on_next = lambda i: print("Got - {0}".format(i)), 8. RxPy — Examples
   on_error = lambda e: print("Error : {0}".format(e)),
   on_completed = lambda: print("Job Done!"),
)

К применению реактивного программирования в Python, конечно, есть вопросы — в языке и так из коробки есть map, reduce и filter, с помощью которых при необходимости можно соорудить свою обработку данных по схожему принципу, не привлекая к работе rxpy. Да и чтение кода с применением rxpy несколько усложняется.


Да, недостатки есть, но, как минимум, с концепцией реактивного программирования нужно быть знакомым — она активно применяется сегодня, например, в клиентском программировании на JS и Swift.


Newspaper


Newspaper


Несколько лет назад мне активно пришлось работать с извлечением текстов статей из разных сайтов. Задача несложная — получи ссылку на документ, выкачай HTML разметку, обработай ее парсером по типу beautiful soup — и вот тебе вся нужная информация. Минус в этом всем один — если сайтов много и все они разные, то работа программиста сводится к откровенно обезьяньему труду — ковырянии в HTML страниц и написании абсолютно однообразных парсеров по извлечению осмысленного контента.


На второй день возни с процессорами разметки и описания селекторов тегов я начал тихонько сходить с ума и задумался об автоматической потрошилке верстки. На глаза мне попалась либа newspaper.


Эта либа автоматически извлекает полезную инфу из новостей, журнальных и блоговых статей и прочих сайтов, где основной контент — это большие блоки текста. Библиотека сама анализирует страницы несложным алгоритмом, находит в коде осмысленный текст и извлекает его — вам вообще не потребуется описывать правила парсинга!


  • Автоматические извлечение текста статьи их страницы
  • Извлечение заглавной картинки поста
  • Полное извлечение всех картинок, ключевых слов и метаданных (автор, время публикации)

from newspaper import Article

url = 'http://fox13now.com/2013/12/30/new-year-new-laws-obamacare-pot-guns-and-drones/'
article = Article(url)
article.download()

#Скачали текст и запустил парсинг
article.parse()

>>> article.authors
['Leigh Ann Caldwell', 'John Honway']

>>> article.publish_date
datetime.datetime(2013, 12, 30, 0, 0)

# А вот тут лежит уже добытый текст! Все достается само, парсить ничего не надо
>>> article.text
'Washington (CNN) -- Not everyone subscribes to a New Year's resolution...'

>>> article.top_image
'http://someCDN.com/blah/blah/blah/file.png'

>>> article.movies
['http://youtube.com/path/to/link.com', ...]

Streamlit


Подразделения датасайнс повально работают в jupyter — идеальной среде для проведения исследований и экспериментов по анализу данных и машинному обучению.


Ппосле экспериментов с кодом и данными, настает момент, когда готовую математическую модель нужно откалибровать и донастроить с менеджерами проекта. Где-то менеджерам нужно попробовать разные входные параметры, где-то нужно посмотреть на графики — короче, мелких правок и тестов хватает.


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


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


image


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


На сегодня все, прошлые питонячие радости смотрите по ссылке.