Найти в Дзене

Введение в Web scraping с Python

Оглавление

Добрый день. Чтобы одновременно убить 2 зайцев (программирование и английский), буду потихоньку выцеплять интересные статьи или туториалы и переводить их. Ссылки на оригиналы и материалы из статьи собрал внизу.

Современный веб-скрейпинг с BeautifulSoup и Selenium.

Краткий обзор.

HTML почти интуитивен. CSS дает прекрасную возможность отделить структуру страницы от её внешнего вида. JavaScript добавляет блестяшек. Это теория. В реальном мире все немного по другому.

В этой статье мы разберем как появляется контент, который мы видим в браузере и как его можно собрать, если необходимо. Если точнее, разберем как получить комментарии из блока внизу статьи. Нашими инструментами будут Python и его шикарные библиотеки: requests, BeautifulSoup, Selenium.

Когда может понадобиться веб-скрейпинг?

Вэб-скрейпинг(Web scraping) — это практика автоматического получения контента с веб страниц, ориентированных на взаимодействие с обычными пользователями. Для этого сначала нужно получить код страницы, спарсить(разобрать) его, а затем уже извлечь необходимую информацию (например ссылки на другие страницы). Обычно скрейпинг применяется только если нет других способов достать необходимую информацию. Идеальный вариант, когда приложения сами предоставляют свой API для доступа к данным. Причины, по которым скрейпинг должен быть вашим «крайним случаем»:

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

- он может быть под запретом (некоторые интернет-приложения принимают защитные меры против скрейпинга)

- он может быть медленным и трудозатратным (если данные, которые нужно вытянуть скрыты за огромным количеством «шума»)

Как сейчас устроены веб-страницы

Чтобы понять, какие задачи перед нами стоят, давайте разберем код какого-нибудь стандартного веб приложения. В статье «Введение в Vagrant» есть несколько комментариев внизу страницы.

Перед тем как мы сможем их получить, нужно найти комментарии в коде страницы.

Смотрим код страницы

Каждый браузер еще с зари времен (1990е) умеет показывать HTML код текущей страницы. Мы видим, что код страницы начинается с огромного куска JavaScript кода, не относящегося напрямую к статье. Вот небольшая часть:

-2

А вот немного самого HTML с этой страницы:

-3

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

Могучий Inline Frame

В этот момент становится понятно, что страница сборная (mash) и блок комментариев выполнен как Iframe (inline frame) элемент. Если кликнуть на зону комментариев правой кнопкой, то вы увидите информацию о iframe и его источниках.

-4

В этом есть смысл, ведь встраивание контента из другого источника — это одна из главных причин использовать iframe элементы. Попробуем найти тэг <iframe> в коде страницы. Опять неудача! Никакого <iframe>.

JavaScript-сгенерированная разметка

Причина нашей ошибки в том, что «просмотр кода страницы» показывает контент, который был получен с сервера, но финальная модель (DOM — document object model), представленная браузером, может сильно отличаться. На определенном этапе JavaScript вступает в игру и может манипулировать моделью как хочет. Iframe элемента нет в коде, т.к. его там и не было, когда страницы была получена с сервера.

Static Scraping vs. Dynamic Scraping

Статический скрейпинг игнорирует JavaScript. Так мы получаем страницы с сервера без обращения к браузеру. Именно то, что видите в «коде страницы» и затем обрабатываете. Если контент, который вы ищете доступен, то нет нужды идти на дальнейшие ухищрения. Однако иногда, как в случае с блоком комментариев разобранном ранее, вам нужен динамический скрейпинг.

Динамический скрейпинг использует ваш браузер или hedaless браузер (браузер без графического интерфейса) и позволяет JavaScript выполнить свою работу, а уже потом считывает содержимое и контент, необходимый вам. Иногда необходимо настроить браузер и симулировать заход «пользователя» чтобы получить нужные данные.

Статический веб-скрейпинг с помощью Requests и BeautifulSoup

Давайте посмотрим, как статический скрейпинг работает. Для этого мы будем использовать 2 замечательных Python библиотеки : requests для получения веб-страницы и BeautifuSoup для парсинга HTML страниц.

Устанавливаем Requests и BeautifulSoup

Сначала установим pipenv, а затем выполним команду pipenv install requests beautifulsoup4

Так вы сможете создать виртуальное окружение. Если используете код с gitlab, можете просто сделать так pipenv install

Получаем страницу

Получение страницы запросом(request) укладывается в одну строчку: r = requests.get(url).

Ответ приходит в виде объекта со множеством характеристик. Наиболее важные — ok и content. Если запрос не удастся, то r.ok будет False и r.content будет содержать ошибку. Контент это поток байтов, который, если работаете с текстом, обычно лучше декодировать используя utf-8 кодировку.

-5

Если все OK, то r.content будет содержать код необходимой веб-страницы (такой же, как и при просмотре "кода страницы")

Находим элемент с помощью BeautifulSoup

Функция get_page() получает данные страницы по ссылке(url), затем декодирует их, используя UTF-8 кодировку и разбирает с помощью HTML парсера, переводя в BeautifulSoup-объект.

-6

Авторские страницы сайта Tuts+ содержат множество обучающих статей. Вот моя авторская страница. На каждой странице до 12 статей. Если вам нужно больше 12, можете перейти на следующую. HTML для каждой статьи закрыт тегом <article>. Следуя инструкции приведенной ниже, можно найти все элементы, относящиеся к статьям на этой странице, провалиться до ссылок и извлечь href атрибут, чтобы получить ссылку на статью.

-7

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

-8

Динамический веб-скрейпинг с Selenium

Статический скрейпинг хорош, чтобы получить список статей, но, как мы видели ранее, блок комментариев был встроен в iframe элемент с помощью JavaScript. Чтобы собрать комментарии, мы должны задействовать браузер и взаимодействовать с моделью страницы через него. Один из лучших инструментов для этого — Selenium.

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

Устанавливаем Selenium

Введите команду, чтобы установить Selenium:pipenv install selenium

Выбираем веб драйвер

Селениуму нужен веб драйвер (браузер, который он будет использовать) для веб-скрепйинга. Обычно не имеет значения, какой именно вы выберете. Мне больше нравится драйвер Chrome. Воспользуйтесь инструкциями в Selenium guide.

Chrome или PhantomJS

В некоторых случаях вы можете решить использовать headless браузер, а именно браузер без графического интерфейса. Теоретически, PhfntomJS это просто еще один драйвер. На практике же, некоторые люди сообщали о задачах, которые правильно решались на драйверах Chrome или Firefox, но ловили какую-либо ошибку на PhantomJS. Так что я предпочитаю просто исключить лишнюю переменную и использовать драйвера привычного браузера.

Подсчитаем комментарии

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

-9

Функция get_comment_count() согласует драйвер Selenium и ссылку. Она использует get() метод с драйвером, чтобы получить ссылку. Это похоже на requests.get(), но таким образом мы получаем живой код модели а не только ответ сервера.

Затем мы получаем заголовок статьи и находим блок с комментариями, использую ИД его родителя disqus_thread. Вот и сам Iframe:

-10

Следующий шаг — получить содержимое iframe элемента. Важно, что мы дожидаемся появления comment-count элемента, потому что комментарии подгружаются динамически и могут быть еще недоступны

-11

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

-12

Заключение

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

Источник: статья