29
Юрий Бабуров (buriy) Webdev, AI, HighLoad Получаем текст веб-страниц из Python и как это работает, или применение эвристик для решения сложных задач (На примере библиотеки readability- lxml)

Получаем текст веб-страниц из Python и как это работает

  • Upload
    pynsk

  • View
    665

  • Download
    5

Embed Size (px)

Citation preview

Page 1: Получаем текст веб-страниц из Python и как это работает

Юрий Бабуров (buriy)Webdev, AI, HighLoad

Получаем текст веб-страниц из Python и как это работает, или применение эвристик для

решения сложных задач

(На примере библиотеки readability-lxml)

Page 2: Получаем текст веб-страниц из Python и как это работает

План действий

Формулируем задачу Из чего состоят новостные веб-страницы? Придумываем алгоритм сами Обобщим наш опыт Пара историй для размышления Рассматриваем альтернативные идеи

Page 3: Получаем текст веб-страниц из Python и как это работает

Зачем нужны новостные статьи Сайты-агрегаторы новостей Сниппеты новостей Текстовые корпуса для лингвистов Анализ потока новостной информации Reading list в Safari

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

Page 4: Получаем текст веб-страниц из Python и как это работает

Формулируем задачу Задачу можно формулировать и решать по-разному,

мы рассмотрим лишь одно из возможных решений. Сайтов нужно обработать много, статей – ещё

больше. Поэтому алгоритм должен работать быстро Но, по возможности, качественно У нас не так много времени на разработку Но надо иметь возможность настройки для важных сайтов Мы можем ограничиться HTML-версиями новостных

статей.

Page 5: Получаем текст веб-страниц из Python и как это работает

Получаем результат$ sudo pip install readability-lxml

$ python -m readability.readability -b -u http://lenta.ru/news/2015/08/26/nishtiak_the_cat/

конечно, то же самое можно сделать и из программы на python, пример будет позднее

Page 6: Получаем текст веб-страниц из Python и как это работает

Как это может работать для самых разных сайтов?

Даю 15 секунд на размышления(только молча)

Page 7: Получаем текст веб-страниц из Python и как это работает

Из чего, из чего сделаны новостные статьи...

Хорошая новостная статья

Page 8: Получаем текст веб-страниц из Python и как это работает

Из чего, из чего сделаны новостные статьи...

Хорошая новостная статья:

Категория Дата и время Заголовок Иллюстрация Текст

Page 9: Получаем текст веб-страниц из Python и как это работает

Из чего, из чего сделаны новостные статьи...

Что нас интересует в первую очередь:

Заголовок Иллюстрация Текст

Page 10: Получаем текст веб-страниц из Python и как это работает

Из чего, из чего сделаны новостные статьи...

Плохая новостная статья:

Page 11: Получаем текст веб-страниц из Python и как это работает

Из чего, из чего сделаны новостные статьи...

Плохая новостная статья:

Социальные иконки Вставки Текстовая и

графическая реклама

Page 12: Получаем текст веб-страниц из Python и как это работает

Из чего, из чего сделаны новостные статьи...

Всё, кроме статьи:

Page 13: Получаем текст веб-страниц из Python и как это работает

Из чего, из чего сделаны новостные статьи...

Всё, кроме статьи:

Подзаголовки Блоки ссылок Рекламные блоки

Page 14: Получаем текст веб-страниц из Python и как это работает

Тоже части веб-страницы

Ссылочные и рекламные блоки Ссылки на другие страницы и общаядля всех страниц информация

Page 15: Получаем текст веб-страниц из Python и как это работает

Как искать текст статьи Чего хотим:

Текст! Много текста рядом!

Не хотим: Ссылочных блоков Блоков с картинками Подзаголовков Маленьких картинок

Текст: Длинные законченные предложения

Заголовки: Короткие предложения без точки в конце

Мы нашли набор критериев, как отличить текст от всего остального.

Page 16: Получаем текст веб-страниц из Python и как это работает

Наше кольцо всевластья: основы Получаем “веса”, оценивая “текстовость”

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

Используем древовидность HTML: узлам-родителям даём бонус за хороших “детей” и “внуков” (50% от веса).

Удаляем нетекстовые блоки (с весом меньше нуля)

Находим блок текста с наибольшим весом – часто это наибольший блок

Надеемся на адекватность авторов веб-странички!

<BODY> <DIV>

В Новосибирске выбрали кота...

Помимо торжественной прогулки...

Блок с иконками <DIV>

ПОСЛЕДНИЕ НОВОСТИ Много ссылок

Page 17: Получаем текст веб-страниц из Python и как это работает

Увы, не всё так просто

Некоторые комментарии бываютдлиннее и лучше, чем текст статьи

Настоящим жадинам нужнонесколько страниц для одной новости

Page 18: Получаем текст веб-страниц из Python и как это работает

Как искать заголовок новости

Даю 15 секунд на размышления(только молча)

Page 19: Получаем текст веб-страниц из Python и как это работает

Как искать заголовок новости

Поисковая оптимизация – шаг к унификации

<title> <H1> или <H2> <H3> и <H4> Ищем заголовок,

похожий на Title

Page 20: Получаем текст веб-страниц из Python и как это работает

Как искать иллюстрации

Думаю, вы уже догадались...

Page 21: Получаем текст веб-страниц из Python и как это работает

Как искать иллюстрации

Положительные факторы: Одна или несколько иллюстраций Большого размера Располагаются посреди текста или рядом

Отрицательные факторы: Много иллюстраций Маленького размера Находятся далеко от текстовых блоков

Page 22: Получаем текст веб-страниц из Python и как это работает

Обобщение – мать учения Использованный приём называется “эвристика” или “эвристический

алгоритм” (heuristic) В библиотеке readability-lxml используется порядка 50 эвристик. Эвристика позволяет дать достаточно хорошое решение в

большинстве случаев, но ошибается временами Позволяет хоть как-то решать задачи, с которыми не справиться

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

компьютер будет придумывать алгоритм вместо нас, то это уже будет называться “машинное обучение” (machine learning)

Page 23: Получаем текст веб-страниц из Python и как это работает

Примеры эвристик и других вероятностных методов

Определить формат файла в большинстве случаев можно по первым байтам

“Email – любая строка, содержащая @ и точку после знака @” “Email – строка, удовлетворяющая этому длинному

регулярному выражению”. Выделение наиболее информативных предложений из текста

(text summarization)

Примеры: Шагомер, Kinect, поиск лиц на фотографии, задача разделения текста на предложения.

Page 24: Получаем текст веб-страниц из Python и как это работает

Другие идеи для задачи поиска текста

Использовать информацию из class=”...” и id=”...”, а также название тега для улучшения критерия хороших и плохих тегов в HTML

Использовать CSS-стили, например display:none Загружать страницу в браузер:

ждать выполнения Javascript определять и использовать координаты текстовых блоков

(текст статьи обычно выше комментариев, посторонние блоки узкие и находятся сбоку)

При поиске заголовка использовать URL (nishtiak_the_cat/).

Page 25: Получаем текст веб-страниц из Python и как это работает

Дополнительные эвристики для readability-lxml

Проблема: получили длинный комментарий вместо короткого текста статьи

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

Ещё одна эвристика. Если есть много статей с одного источника: Можно классифицировать статьи по качеству: например, полученные

одинаковые статьи по разным URL – плохие, остальные тексты – хорошие. Если в статьях повторяются определённые элементы, возможно, это

невычищенный мусор. Используя статистические методы: через machine learning или вручную

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

Page 26: Получаем текст веб-страниц из Python и как это работает

Жизненный цикл эвристики Помните, кому-то придётся поддерживать ваш код, поэтому

обязательно комментируйте эвристики. Выбор способа за вами, скажем

#Hack: … , docstring, ссылка на сайт-источник регулярного выражения или ссылка на баг, из-за которого эвристика появилась в вашем коде.

Page 27: Получаем текст веб-страниц из Python и как это работает

Определение похожести двух текстов

def calc_quality(feed_text, article_text): """ Returns a number between 0 and 100 """ feed_words = set(feed_text.split()) article_words = set(article_text.split()) if not article_words: return 20 intersection = len(article_words & feed_words) return int(10 * min(10, max(5 + intersection - 0.6 * len(feed_words), 0)))

-------------------------------------------------------

from readability.readability import Documentimport urllibhtml = urllib.urlopen(url).read()readable_article = Document(html).summary()readable_title = Document(html).short_title()

Page 28: Получаем текст веб-страниц из Python и как это работает

Сортируем тексты по похожестиclass MyDocument(Document): def select_best_candidate(self, candidates): if not candidates: return None feed_text = html2text(self.article.feed_snippet) if not feed_text: feed_text = self.article.title sorted_candidates = sorted(candidates.values(), reverse=True, key=lambda x: x['content_score']) for candidate in sorted_candidates[:50]: elem_text = html2text(tounicode(candidate['elem'])) quality = calc_quality(feed_text, elem_text) if quality > 50: candidate['content_score'] += 10 elif quality > 0: candidate['content_score'] += 1

sorted_candidates = sorted(candidates.values(), reverse=True, key=lambda x: x['content_score'])

return sorted_candidates[0]

Page 29: Получаем текст веб-страниц из Python и как это работает

Спасибо за внимание

Ваши вопросы