Почему стоит научиться «парсить» сайты, или как написать свой первый парсер на Python
Для начала давайте разберемся, что же действительно означает на первый взгляд непонятное слово — парсинг. Прежде всего это процесс сбора данных с последующей их обработкой и анализом. К этому способу прибегают, когда предстоит обработать большой массив информации, с которым сложно справиться вручную. Понятно, что программу, которая занимается парсингом, называют — парсер. С этим вроде бы разобрались.
Перейдем к этапам парсинга.
- Поиск данных
- Извлечение информации
- Сохранение данных
И так, рассмотрим первый этап парсинга — Поиск данных.
Так как нужно парсить что-то полезное и интересное давайте попробуем спарсить информацию с сайта work.ua.
Для начала работы, установим 3 библиотеки Python.
pip install beautifulsoup4
Без цифры 4 вы ставите старый BS3, который работает только под Python(2.х).
pip install requests
pip install pandas
Теперь с помощью этих трех библиотек Python, можно проанализировать нашу веб-страницу.
Второй этап парсинга — Извлечение информации.
Попробуем получить структуру html-кода нашего сайта.
Давайте подключим наши новые библиотеки.
И сделаем наш первый get-запрос.
Статус 200 состояния HTTP — означает, что мы получили положительный ответ от сервера. Прекрасно, теперь получим код странички.
Получилось очень много, правда? Давайте попробуем получить названия вакансий на этой страничке. Для этого посмотрим в каком элементе html-кода хранится эта информация.
У нас есть тег h2 с классом «add-bottom-sm», внутри которого содержится тег a. Отлично, теперь получим title элемента a.
Хорошо, мы получили названия вакансий. Давайте спарсим теперь каждую ссылку на вакансию и ее описание. Описание находится в теге p с классом overflow. Ссылка находится все в том же элементе a.
Получаем такой код.
И последний этап парсинга — Сохранение данных.
Давайте соберем всю полученную информацию по страничке и запишем в удобный формат — csv.
Руководство по вэб-скрепингу на Python: приёмы и хитрости
Как-то я хотела купить авиабилеты и заметила, что цены изменяются несколько в течение дня. Я попыталась выяснить, когда наступает самый лучший момент для покупки билетов, но не нашла в Интернете ничего, что бы могло мне помочь решить эту задачу. Тогда я написала небольшую программу для автоматического сбора данных в Интернете — так называемую программу скрепинга. Программа извлекла информацию по моему запросу для определенного пункта назначения на выбранные мной даты и показала мне, когда стоимость становится минимальной.
Веб-скрепинг — это метод автоматизированного извлечения данных с веб-сайтов.
Я имею большой опыт веб-скрепинга и хочу с вами поделиться.
Этот пост предназначен для тех, кому интересно узнать об общих шаблонах проектирования, подвохах и правилах, связанных с веб-скрепингом. В статье представлено несколько реальных примеров и перечень типовых задач, таких как, например, что делать, чтобы вас не обнаружили, что можно делать, а что не следует и, наконец, как ускорить работу вашего скрепера с помощью распараллеливания.
Все примеры будут сопровождаться фрагментами кода на Python, так что вы можете сразу же ими воспользоваться. В этом материале также будет показано, как привлекать к работе полезные пакеты Python.
Реальные примеры
Существует различные причины и варианты необходимости использования сбора (скрэпинга) данных в Интернете. Позвольте мне перечислить некоторые из них:
-
, чтобы определить имеется ли в наличии одежда, которую вы хотите купить, со скидкой нескольких брендов одежды, собирая данные о них с вэб-страниц
- стоимость авиабилетов может меняться несколько раз в течение дня. Можно сканировать веб-сайт и дождаться момента, когда цена будет снижена
- проанализировать веб-сайты, чтобы определить, должна ли быть стартовая стоимость продажи низкой или высокой, чтобы привлечь больше участников на аукцион или коррелирует ли длительность проведения аукциона с более высокой ценой конечной ценой продажи
Руководство
- Применяемые пакеты
- Основной программный код
- Распространенные ошибки
- Общие правила
- Ускорение ‑ распараллеливание
Прежде чем мы приступим: БУДЬТЕ аккуратны с серверами; вы же НЕ ХОТИТЕ сломать вэб-сайт.
1. Известные пакеты и инструменты
Для веб-скрэпинга нет универсального решения, поскольку способ, с помощью которого хранится на каждом из веб-сайтов обычно специфичны. На самом деле, если вы хотите собрать данные с сайта, вам необходимо понять структуру сайта и, либо создать собственное решение, либо воспользоваться гибким и перенастраиваемым вариантом уже готового решения.
Изобретать колесо здесь не нужно: существует множество пакетов, которые скорее всего, вам вполне подойдут. В зависимости от ваших навыков программирования и предполагаемого варианта использования вы можете найти разные более или менее полезные для себя пакеты.
1.1 Проверяем параметры
Чтобы вам было проще проверять HTML-сайт, воспользуйтесь опцией инспектора в вашем вэб-браузере.
Раздел веб-сайта, который содержит мое имя, мой аватар и мое описание, называется hero hero—profile u-flexTOP (любопытно, что Medium называет своих писателей героями:)). Класс <h1>, который содержит мое имя, называется ui-h2 hero-title , а описание содержится в описании героя <p> классом ui-body hero-description .
Вы можете более подробно познакомиться с HTML-тэгами и различиями между классами и id здесь.
1.2 Скрэпинг
Существует отдельная готовая к использованию библиотека для извлечения данных под названием Scrapy. Кроме извлечения HTML, этот пакет располагает большим количеством функций, таких как экспорт данных в различные форматы, создание лог-файлов и т.д. Это достаточно гибкий и настраиваемый вариант: запуск отдельных скрэперов на разных процессах , отключение cookies (некоторые сайты используют cookies для идентификации ботов) и установка задержек загрузки (веб-сайт может быть перегружен из-за огромного количества запросов на сканирование). Его также можно использовать для извлечения данных с помощью API. Однако для начинающих программистов пакет, скорее всего, будет несколько сложноват: вам придется прочитать руководства и разобраться с примерами, прежде чем вы сможете приступить к работе.
В моем случае я воспользовалась готовым методом «из коробки»: я просто хотела извлечь ссылки со всех страниц, получить доступ по каждой ссылке и извлечь из нее информацию.
1.3 BeautifulSoup с библиотекой Request
BeautifulSoup — это библиотека, позволяющая сделать синтаксический разбор (парсинг) HTML-кода. Кроме того, вам также потребуется библиотека Request , которая будет отображать содержимое URL-адреса. Однако, вы также должны позаботиться и о решении ряда прочих вопросов, таких как обработка ошибок, экспорт данных, распараллеливание и т.д.
Я выбрала BeautifulSoup, поскольку эта библиотека помогла мне понять сколько всего Scrapy может делать самостоятельно и, я надеюсь, помогла мне быстрее научиться на своих собственных ошибках.
2. Основной программный код
Начать скэпить вэб-сайт очень просто. В большинстве случаев просматриваете HTML-сайт, вы обнаружите те классы и идентификаторы, которые могут вам могут понадобиться. Допустим, у нас есть следующая структура html, и мы хотим извлечь элементы main_price .
Примечание: элемент discounted_price является необязательным.
Основной код вэб-скрепера должен импортировать библиотеки, выполнить запрос, проанализировать html и затем найти класс class main_price .
Может случиться так, что класс main_price находится в другом разделе веб-сайта. Чтобы избежать извлечения ненужного класса main_price из какой-либо другой части веб-страницы, мы могли бы сначала обратиться к id listings_prices и только затем найти все элементы с классом main_price .
3. Распространенные ошибки
3.1 Check robots.txt
Правила скрэпинга веб-сайтов можно найти в файле robots.txt. Вы можете найти его, написав слова «robots.txt» после имени домена, например так: www.website_to_scrape.com/robots.txt . Эти правила определяют, какие части веб-сайтов не могут быть автоматически извлечены или как часто боту разрешено запрашивать данные со страницы. Большинство не заботятся об этих правилах, но все же постарайтесь хотя бы почитать их, даже если вы и не планируете следовать им.
3.2 HTML может быть злом
HTML-теги могут содержать идентификатор (id), класс или сразу оба этих элемента. Идентификатор (т.е. id) HTML описывает уникальный идентификатор, а класс HTML не является уникальным. Изменения в имени или элементе класса могут либо сломать ваш код, либо выдать вам неправильные результаты.
Есть два способа избежать, или, по крайней мере, предупредить это:
• Используйте конкретный идентификатор id , а не class , поскольку он с меньшей вероятностью будет изменен
- Проверьте, не возвращается ли элемент значение None.
Однако, поскольку некоторые поля могут быть необязательными (например, discounted_price в нашем HTML-примере), соответствующие элементы не будут отображаться в каждом списке. В этом случае вы можете подсчитать процентное соотношение частоты возврата None конкретным элементом в списке. Если это 100%, вы, возможно, захотите проверить, было ли изменено имя элемента.
3.3 Обмануть программу-агент
Каждый раз, когда вы посещаете веб-сайт, он получает информацию о вашем браузере через пользовательский агент. Некоторые веб-сайты не будут показывать вам какой-либо контент, если вы не предоставите им пользовательский агент. Кроме того, некоторые сайты предлагают разные материалы для разных браузеров. Веб-сайты не хотят блокировать разрешенных пользователей, но вы будете выглядеть подозрительно, если вы отправите 200 одинаковых запросов в секунду с помощью одного и того же пользовательского агента. Выход из этой ситуации может заключаться в том, чтобы сгенерировать (почти) случайного пользовательского агента или задать его самостоятельно.
3.4 Время ожидания запроса
По умолчанию Request будет продолжать ожидать ответ в течение неопределенного срока. Поэтому рекомендуется установить параметр таймаута.
3.5 Я заблокирован?
Частое появление кодов состояния, таких как 404 (не найдено), 403 (Запрещено), 408 (Тайм-аут запроса), может указывать на то, что вы заблокированы. Вы можете проверить эти коды ошибок и действовать соответственно.
Кроме того, будьте готовы обработать исключения из запроса.
3.6 Смена IP
Даже если вы рандомизировали своего пользовательского агента, все ваши запросы будут отправлены с одного и того же IP-адреса. Это вполне нормально, поскольку библиотеки, университеты, а также компании имеют всего несколько IP-адресов. Однако, если очень много запросов поступает с одного IP-адреса, сервер может это обнаружить.
Использование общих прокси, VPN или TOR может помочь вам стать незаметным;)
Если вы используете общий прокси-сервер, веб-сайт увидит IP-адрес прокси-сервера, а не ваш. VPN соединяет вас с другой сетью, а IP-адрес поставщика VPN будет отправлен на веб-сайт.
3.7 Ловушки для хакеров
Ловушки для хакеров — это средства для обнаружения сканеров или скреперов.
Такими средствами могут быть «скрытые» ссылки, которые не видны пользователям, но могут быть извлечены скреперами и/или вэб-спайдерами. Такие ссылки будут иметь набор стилей CSS display:none , их можно смешивать, задачая цвет фона или даже перемещаясь из видимой области страницы. Как только ваша программа посещает такую ссылку, ваш IP-адрес может быть помечен для дальнейшего расследования или даже мгновенно заблокирован.
Другой способ обнаружить хакеров — это добавить ссылки с бесконечно глубокими деревьями директорий. В этом случае вам нужно ограничить количество загруженных страниц или ограничить глубину обхода.
4. Общие правила
- Перед началом скрэпинга проверьте, есть ли у вас возможность воспользоваться публичными API. Публичные API предоставляют более простой и быстрый (и законный) поиск данных, по сравнению с веб-скрэпингом. Посмотрите API Twitter, который предоставляет API для различных целей.
- Если вы скрэпите много данных, вы можете воспользоваться базой данных, чтобы иметь возможность быстро анализировать получать данные с Интернета. В этом руководстве описано, как создать локальную базу данных с помощью Python.
- Будьте вежливы, терпеливы и уважительны. Как следует из этого ответа, рекомендуется оповещать пользователей о том, что вы собираете данные с их веб-сайта, чтобы они могли лучше отреагировать на возможные проблемы, причиной которых может стать ваш бот.
Опять таки, не перегружайте веб-сайт, отправляя сотни запросов в секунду.
5. Ускорение ‑ распараллеливание
Если вы решитесь на распараллеливание своей программы, будьте осторожны с реализацией, чтобы не “свалить” сервер. Обязательно прочитайте раздел «Распространенные ошибки», приведенный выше. Ознакомьтесь с определениями параллельного и последовательного выполнения, процессоров и потоков здесь и здесь.
Если вы извлекаете большое количество информации со страницы и выполняете некоторую предварительную обработку данных, количество повторных запросов в секунду, которое вы отправляете на страницу, может быть относительно низким.
В своем другом проекте я собирала цены на аренду квартиры и сделала для этого довольно сложную предварительную обработку данных, в результате чего мне удалось отправлять только один запрос в секунду. Чтобы собрать объявления размером в 4K, моя программа должна проработать около часа.
Чтобы отправлять запросы параллельно, вы можете воспользоваться пакетом multiprocessing.
Допустим, у нас есть 100 страниц, и мы хотим назначить каждому процессу равное количество страниц для обработки. Если n — количество процессоров, то вы можете равномерно распределить все страницы на n частей и назначить каждую часть отдельному процессору. Каждый процесс будет иметь свое имя, свою целевую функцию и свои аргументы для работы. После этого имя процесса можно использовать для включения записи данных в определенный файл.
Я назначила 1K страниц для каждого из 4-х процессоров, имевшихся у меня в распоряжении, в результате было создано 4 повторных запроса в секунду, что сократило время сбора данных моей программой до 17 минут.
Парсинг страниц на Python. Parser на Python
Рано или поздно любой Python-программист сталкивается с задачей скопировать какой-нибудь материал с сайта. Так как страниц на нём достаточно много, терять время на ручное копирование — не самый лучший выход. К тому же, языки программирования затем и нужны, чтобы избавлять нас от рутинной работы, автоматизируя решение различных задач. Если же говорить о работе с HTML, то в Python есть отличные библиотеки для этого. Они позволяет парсить как сайты, так и обычные HTML-документы.
Парсер — что это вообще такое?
Если вы ещё не сталкивались с этим понятием, то давайте поговорим о нём подробнее. Итак, парсером называют скрипт, который осуществляет синтаксический анализ данных с последующих их отбором и группировкой в БД либо электронную таблицу. Эта программа выполняет сопоставление линейной последовательности слов с учётом правил языка.
Алгоритм работы парсера: 1. Получение доступа к сети и API веб-ресурса, его скачивание. 2. Извлечение, исследование и обработка скачанных данных. 3. Экспорт полученной информации.
По сути, парсинг может проводиться с применением разных языков программирования, но проще всего показать его именно на Python, благодаря простому синтаксису.
Что касается назначения парсинга, то он используется в разных целях, например: — сбор информации для своего сайта; — индексация веб-страниц; — получение данных, не являющихся интеллектуальной собственностью и т. д.
Но чтобы парсер полноценно выполнил поставленные задачи, нужно подготовить среду, о чём и поговорим.
Готовим к работе скрипт парсинга на Python
Подготовка включает в себя 2 этапа: сначала мы должны освежить свои знания в некоторых областях, а потом можно приступить и к подготовке библиотек.
Итак, для успешного парсинга вам потребуются: 1. Знание PHP, HTML, CSS, JavaScript. Они нужны для первичного анализа и понимания кода страницы, с которой и будем осуществлять парсинг. Не стоит думать, что всё так просто, ведь порой и опытный специалист не может разобраться в структуре сайта, написанного на HTML. 2. Знание и понимание, как применять библиотеки HTML-парсинга на Python, а также регулярные выражения. Это поможет разобраться с проблемами, связанными с невалидным кодом. 3. Основы объектно-ориентированного программирования (желательно). 4. Знания баз данных, например, MySQL. Это необходимо для обработки выходных данных.
Вышеперечисленное — базис, владея которым HTML-парсинг не вызовет у вас затруднений. Также было бы неплохо уметь работать с иерархическими структурами, XML и JSON.
Переходим ко второй части — библиотекам. Вот основные: — LXML. Пакет, имеющий поддержку XLST и XPath. Отличается богатым функционалом по обработке разных API; — GRAB. Очень распространённый инструмент, работает с DOM, может выполнять автозаполнение форм, обрабатывать перенаправление с сайтов; — Beautiful Soup. Прекрасно справляется со структурным разбором сайта, а также с обработкой невалидного кода HTML.
Устанавливаем библиотеку Beautiful Soup (Linux)
Прекрасным преимуществом этой библиотеки является наличие персонального алгоритма структурирования HTML-кода. А это уже позволяет сэкономить разработчику время, что не может не радовать. Итак, устанавливаем:
Установив нужные модули, можем парсить сайт. В результате мы получим его структурированный код:
Чтобы выполнить поиск по ссылкам:
А вот так работает парсер DIV-блоков:
Если хотим получить ссылки на изображения:
Как видим, ничего сложного нет. Но если хотите узнать больше, вы всегда можете записаться на курс «Разработчик Python» в OTUS!
Введение в веб-парсинг на Python.
Веб-скарпинг — это автоматизированный процесс сбора данных с сайта.
Интернет – является центром всей информации на Земле, к сожалению, многая информация не является правдивой. Множество дисциплин, таких как : data science, business intelligence стараются искать истинную информацию и получать из неё пользу для бизнеса.
В данном гайде мы научимся:
— Парсить веб-сайт используя string методы и обычные выражения
— Парсить используя HTML parser
— Взаимодействовать с формами и другими компонентами сайта
Сбор информации с веб-сайта
Повторим ещё раз, веб-скрапинг — это автоматизированный сбор данных с сайтов. Но некоторые сайты запрещают парсить их данные при помощи того инструмента, который мы разработаем с вами в нынешнем гайде. Сайты могут запрещать парсить свои данные по след. Причинам:
- Количество запросов. Сайт может просто не справиться и затормозить.
- Важная информация.
Ваш первый Web scraper
Первый пакет, который мы используем, называется urlib. Он поможет нам работать с url. Данный модуль содержит urlopen() его нужно импортировать.
Далее присваиваем переменной url адрес в формате String.
Для того чтобы открыть данный сайт в python:
urlopen() возвращает нам объект типа HTTPResponse
Для того чтобы прочитать объект HTTPResponse нужно воспользоваться методом .read() далее декодировать файл при помощи .decode():
Теперь вы можете вывести данные переменной, чтобы увидеть контент сайта.
И когда у вас есть HTML как текст, вы можете извлечь информацию из него разными способами.
Извлекаем файлы из HTML методами String объекта
Одним из методов извлечения информации HTML файла могут быть string методы. Например, .find() для поиска через текст .
.fing() возвращает индекс первого входа нужного нам символа/тега. Покажем на примере «<title>» методом .find().
Для того чтобы найти начало заголовка нам нужно к индексу добавить длину тега «<title>».
Также можем найти место где заканчивается «<title>»:
Наконец, мы можем извлечь всё что находится в «<title>», зная первый и последний индекс:
На самом деле, HTML файл может быть намного менее предсказуемым, чем на Aphrodite странице. Поэтому далее мы вам покажем другой способ, который может решить эту задачу.
Регулярные выражения
Регулярные выражения — это паттерны, которые используются для поиска внутри текста типа string. Для этого нам нужна библиотека re.
Мы импортируем модуль re.
Регулярные выражения используют специальные метасимволы для определения разных паттернов. Например символ «*» разрешает вводить любые символы после себя.
Покажем на примере .findall() мы будем искать все совпадения с требуемым для нас выражением (первый элемент — то что мы ищем, второй — в каком тексте).
Используя параметр re.IGNORECASE позволяет методу не учитывать регистр.
Метод .replace() — заменяет все символы в тексте на требуемые нам символы.
Метод .sub() — «<.*>» для замены всего что находится между < и >.
Давайте взглянем ближе на регулярные выражения:
- <title*?> — отмечает открытие тега «title»
- *? — отмечает весь текст после открытие тега «<title>»
- </title*?> — отмечает элемент, который закрывает тег.
HTML парсер на Python
Ладно, хватит играться и развлекаться пора использовать серьёзные вещи для парсинг. К нашему счастью, в библиотеках Python есть множество инструментов, которые созданы для разных задач. Для парсинга нам подойдет Beautiful soup.
Скачиваем Beautiful soup
Теперь, вернёмся в едитор.
Создание объекта типа BeautifulSoup
Наша программа совершит 3 действия:
- Откроет URL
- Прочитает элементы и переведёт их в String
- Присвоит это объекту типа BeautifulSoup
При создании переменной «soup» мы передаём два аргумента, первый это сайт, который мы парсим, второй — какой парсер использовать.
Использование объекта BeautifulSoup. Методы:
Как можно заметить, есть много пустых строк, это результат появления символов новой строки в тексте HTML. Их можно убрать используя метод .replace() .
Если вам нужно что то найти, используйте .find()
Данная команда возвращает все теги <img>.
Каждый объект становится тегом, поэтому можно использовать методы.
Даст нам имя переменной
Этот метод даст нам путь к файлу, например:
Можем увидеть что находится в заголовке
.string
Этот метод убирает теги, покажем на примере title:
Взаимодействие с HTML формами
Библиотека urllib идеально подходит для сбора информации с сайта, но иногда нам приходится взаимодействовать с сайтом, заполнять формы, нажать на кнопку. В этом нам поможет модуль MechanicalSoup.
Устанавливаем модуль
Создаём объект типа Browser
Можем запросить url
Если мы проверим «page» , то нам вернётся 200 — это значит что с сайтом всё в порядке. Если вернётся 404 или 500, то есть ошибка со стороны сайта/сервера.
Показывает нам структуру HTML
Взаимодействие с сайтом в реальном времени
Иногда, нужно получать информацию с сайта в реальном времени. К примеру, нажимать кнопку «Обновить», что не было самым приятным, но теперь всё изменилось.
Теперь мы можем использовать .get() объекта Browser.
Во-первых, нужно определить какой элемент требует обновления, скорее всего нужно просто найти id.
Давайте на примере разберёмся.
В этом примере, метод .select() ищет элемент с id=result(#result) .
Прежде всего, советуем установить промежуток, чтобы сайт успевал перезагружаться. Используйте time.sleep(5) — 5 секунд.
Когда вы запустите программу, вы сразу увидите первый результат, который будет выведен на консоль. Далее будет перерыв в 10 секунд и всё повторится.
После 4 циклов программа остановится.
Используя такую технику, вы сможете собирать данные сайта в реальном времени, но будьте осторожны, слишком частые запросы буду подозрительны для сайта. Иначе ваш ip будет заблокирован и не будет возможности зайти на него.
Так же возможно сломать сервер, на котором хостится сайт, поэтому советуем читать «Правила пользования» (Terms of use)
Заключение
Python уникальный инструмент для множества задач. В данном уроке мы научились собирать информацию с сайта и переводить его в текст.
Только не забывайте, не все хотят делиться информацией в интернете. Всегда читайте Правила пользования, уважайте других контент-мейкеров.