Как спарсить html файл python
BeautifulSoup4 (bs4) - это библиотека Python для извлечения данных из файлов HTML и XML. Для естественной навигации, поиска и изменения дерева HTML, модуль BeautifulSoup4, по умолчанию использует встроенный в Python парсер | html.parser |. BS4 так же поддерживает ряд сторонних парсеров Python, таких как lxml , html5lib и xml (для разбора XML-документов).
Установка BeautifulSoup4 в виртуальное окружение:
Содержание:
Выбор парсера для использования в BeautifulSoup4.
BeautifulSoup4 представляет один интерфейс для разных парсеров, но парсеры неодинаковы. Разные парсеры, анализируя один и того же документ создадут различные деревья HTML. Самые большие различия будут между парсерами HTML и XML. Так же парсеры различаются скоростью разбора HTML документа.
Если дать BeautifulSoup4 идеально оформленный документ HTML, то различий построенного HTML-дерева не будет. Один парсер будет быстрее другого, но все они будут давать структуру, которая выглядит точно так же, как оригинальный документ HTML. Но если документ оформлен с ошибками, то различные парсеры дадут разные результаты.
Различия в построении HTML-дерева разными парсерами, разберем на короткой HTML-разметке: <a></p> .
Парсер lxml .
- Для запуска примера, необходимо установить модуль lxml .
- Очень быстрый, имеет внешнюю зависимость от языка C.
- Нестрогий.
Обратите внимание, что тег <a> заключен в теги <body> и <html> , а висячий тег </p> просто игнорируется.
Парсер html5lib .
- Для запуска примера, необходимо установить модуль html5lib .
- Ну очень медленный.
- Разбирает страницы так же, как это делает браузер, создавая валидный HTML5.
Обратите внимание, что парсер html5lib НЕ игнорирует висячий тег </p> , и к тому же добавляет открывающий тег <p> . Также html5lib добавляет пустой тег <head> ( lxml этого не сделал).
Встроенный в Python парсер html.parser .
- Не требует дополнительной установки.
- Приличная скорость, но не такой быстрый, как lxml .
- Более строгий, чем html5lib .
Как и lxml , встроенный в Python парсер игнорирует закрывающий тег </p> . В отличие от html5lib , этот парсер не делает попытки создать правильно оформленный HTML-документ, добавив теги <html> или <body> .
Вывод: Парсер html5lib использует способы, которые являются частью стандарта HTML5, поэтому он может претендовать на то, что его подход самый "правильный".
Основные приемы работы с BeautifulSoup4.
Чтобы разобрать HTML-документ, необходимо передать его в конструктор класса BeautifulSoup() . Можно передать строку или открытый дескриптор файла:
Первым делом документ конвертируется в Unicode, а HTML-мнемоники конвертируются в символы Unicode:
Дальнейшие примеры будут разбираться на следующей HTML-разметке.
Передача этого HTML-документа в конструктор класса BeautifulSoup() создает объект, который представляет документ в виде вложенной структуры:
Навигация по структуре HTML-документа:
Перемещаться по одному уровню можно при помощи атрибутов .previous_sibling и .next_sibling . Например, в представленном выше HTML, теги <a> обернуты в тег <p> - следовательно они находятся на одном уровне.
Так же можно перебрать одноуровневые элементы данного тега с помощью .next_siblings или .previous_siblings .
Атрибут .next_element строки или HTML-тега указывает на то, что было разобрано непосредственно после него. Это могло бы быть тем же, что и .next_sibling , но обычно результат резко отличается.
Возьмем последний тег <a> , его .next_sibling является строкой: конец предложения, которое было прервано началом тега <a> :
Однако .next_element этого тега <a> - это то, что было разобрано сразу после тега <a> - это слово Tillie, а не остальная часть предложения.
Это потому, что в оригинальной разметке слово Tillie появилось перед точкой с запятой. Парсер обнаружил тег <a> , затем слово Tillie, затем закрывающий тег </a> , затем точку с запятой и оставшуюся часть предложения. Точка с запятой находится на том же уровне, что и тег <a> , но слово Tillie встретилось первым.
Атрибут .previous_element является полной противоположностью .next_element . Он указывает на элемент, который был обнаружен при разборе непосредственно перед текущим:
При помощи атрибутов .next_elements и .previous_elements можно получить список элементов, в том порядке, в каком он был разобран парсером.
Извлечение URL-адресов.
Одна из распространенных задач, это извлечение URL-адресов, найденных на странице в HTML-тегах <a> :
Извлечение текста HTML-страницы.
Другая распространенная задача - извлечь весь текст со HTML-страницы:
Поиск тегов по HTML-документу:
Найти первый совпавший HTML-тег можно методом BeautifulSoup.find() , а всех совпавших элементов - BeautifulSoup.find_all() .
Поиск тегов при помощи CSS селекторов:
Поиск тега под другими тегами:
Поиск тега непосредственно под другими тегами:
Поиск одноуровневых элементов:
Поиск тега по классу CSS:
Поиск тега по ID:
Дочерние элементы.
Извлечение НЕПОСРЕДСТВЕННЫХ дочерних элементов тега. Если посмотреть на HTML-разметку в коде ниже, то, непосредственными дочерними элементами первого <ul> будут являться три тега <li> и тег <ul> со всеми вложенными тегами.
Извлечение ВСЕХ дочерних элементов. Эта операция похожа на рекурсивный обход HTML-дерева в глубину от выбранного тега.
Обратите внимание, что простой текст, который находится внутри тега, так же считается дочерним элементом этого тега.
Если внутри тега есть более одного дочернего элемента (как в примерен выше) и необходимо извлечь только текст, то можно использовать атрибут .strings или генератор .stripped_strings .
Генератор .stripped_strings дополнительно удаляет все переводы строк \n и пробелы между тегами в исходном HTML-документе.
Родительские элементы.
Что бы получить доступ к родительскому элементу, необходимо использовать атрибут .parent .
Taк же можно перебрать всех родителей элемента с помощью атрибута .parents .
Изменение имен тегов HTML-документа:
Изменение HTML-тега <p> на тег <div> :
Добавление новых тегов в HTML-документ.
Добавление нового тега в дерево HTML:
Добавление новых тегов до/после определенного тега или внутрь тега.
Удаление и замена тегов в HTML-документе.
Удаляем тег или строку из дерева HTML:
Заменяем тег и/или строку в дереве HTML:
Изменение атрибутов тегов HTML-документа.
У тега может быть любое количество атрибутов. Тег <b > имеет атрибут id , значение которого равно boldest . Доступ к атрибутам тега можно получить, обращаясь с тегом как со словарем:
Парсинг — это распространенный способ получения данных из интернета для разного типа приложений. Практически бесконечное количество информации в сети объясняет факт существования разнообразных инструментов для ее сбора. В процессе скрапинга компьютер отправляет запрос, в ответ на который получает HTML-документ. После этого начинается этап парсинга. Здесь уже можно сосредоточиться только на тех данных, которые нужны. В этом материале используем такие библиотеки, как Beautiful Soup, Ixml и Requests. Разберем их.
Установка библиотек для парсинга
Чтобы двигаться дальше, сначала выполните эти команды в терминале. Также рекомендуется использовать виртуальную среду, чтобы система «оставалась чистой».
Поиск сайта для скрапинга
Из него можно было бы создать, например, хранилище имен авторов, тегов или самих цитат. Но как это сделать? Сперва нужно изучить исходный код страницы. Это те данные, которые возвращаются в ответ на запрос. В современных браузерах этот код можно посмотреть, кликнув правой кнопкой на странице и нажав «Просмотр кода страницы».
На экране будет выведена сырая HTML-разметка страница. Например, такая:
На этом примере можно увидеть, что разметка включает массу на первый взгляд перемешенных данных. Задача веб-скрапинга — получение доступа к тем частям страницы, которые нужны. Многие разработчики используют регулярные выражения для этого, но библиотека Beautiful Soup в Python — более дружелюбный способ извлечения необходимой информации.
Создание скрипта скрапинга
В PyCharm (или другой IDE) добавим новый файл для кода, который будет отвечать за парсинг.
Отрывок выше — это лишь начало кода. В первую очередь в верхней части файла выполняется импорт библиотек requests и Beautiful Soup. Затем в переменной url сохраняется адрес страницы, с которой будет поступать информация. Эта переменная затем передается функции requests.get() . Результат присваивается переменной response . Дальше используем конструктор BeautifulSoup() , чтобы поместить текст ответа в переменную soup . В качестве формата выберем lxml . Наконец, выведем переменную. Результат должен выглядеть приблизительно вот так.
Вот что происходит: ПО заходит на сайт, считывает данные, получает исходный код — все по аналогии с ручным подходом. Единственное отличие в том, что в этот раз достаточно лишь одного клика.
Прохождение по структуре HTML
HTML — это HyperText Markup Language («язык гипертекстовой разметки»), который работает за счет распространения элементов документа со специальными тегами. В HTML есть много разнообразных тегов, но стандартный шаблон включает три основных: html , head и body . Они организовывают весь документ. В случае со скрапингом интерес представляет только тег body .
Написанный скрипт уже получает данные о разметке из указанного адреса. Дальше нужно сосредоточиться на конкретных интересующих данных.
Если в браузере воспользоваться инструментом «Inspect» (CTRL+SHIFT+I), то можно достаточно просто увидеть, какая из частей разметки отвечает за тот или иной элемент страницы. Достаточно навести мышью на определенный тег span , как он подсветит соответствующую информацию на странице. Можно увидеть, что каждая цитата относится к тегу span с классом text .
Таким образом и происходит дешифровка данных, которые требуется получить. Сперва нужно найти некий шаблон на странице, а после этого — создать код, который бы работал для него. Можете поводить мышью и увидеть, что это работает для всех элементов. Можно увидеть соотношение любой цитаты на странице с соответствующим тегом в коде.
Скрапинг же позволяет извлекать все похожие разделы HTML-документа. И это все, что нужно знать об HTML для скрапинга.
Парсинг HTML-разметки
В HTML-документе хранится много информации, но благодаря Beautiful Soup проще находить нужные данные. Порой для этого требуется всего одна строка кода. Пойдем дальше и попробуем найти все теги span с классом text . Это, в свою очередь, вернет все теги. Когда нужно найти несколько одинаковых тегов, стоит использовать функцию find_all() .
Данные есть везде, на каждом посещенном вами сайте. Чаще всего они уже представлены в читаемом текстовом формате, пригодном для использования в новом проекте, однако, несмотря на то, что нужный текст всегда можно скопировать и вставить прямо со страницы сайта, когда речь заходит о больших данных — о тексте с десятка тысяч веб-сайтов — скрейпинг приходит на помощь.
Обучаться веб-скрейпингу (web-scraping) поначалу сложно, однако если вы начнете своё знакомство с большими данными, используя правильные инструменты, то предстоящий вам путь существенно облегчится.
В пошаговом руководстве вы узнаете, как сделать скрейпинг нескольких страниц веб-сайта с помощью самой простой и популярной библиотеки Python для скрейпинга: Beautiful Soup.
Руководство состоит из двух разделов. В первом разделе речь пойдет о том, как осуществить скрейпинг одной страницы, а во втором — о том, как скрейпить сразу нескольких страниц с помощью примера кода, из первого раздела.
Список рассматриваемых в руководстве тем:
- Что нужно для начала веб-скрейпинга?
- Установка, запуск и настройка Python-библиотеки Beautiful Soup.
- Раздел 1: cкрапинг одной страницы:
— Импорт библиотек.
— Получение HTML-содержимого веб-сайта.
— Анализ веб-сайта и его HTML-разметки.
— Одновременное нахождение нескольких HTML-элементов с помощью Beautiful Soup.
— Экспорт данных в txt -файл. - Раздел 2: cкрапинг нескольких страниц:
— Получение атрибута href .
— Нахождение нескольких элементов с помощью Beautiful Soup.
— Переход по каждой из необходимых ссылок.
Что нужно для начала веб-скрейпинга?
Перед началом руководства, убедитесь, что на вашем компьютере установлен Python 3 версии.
Давайте начнем ознакомление с пособием для новичков по настройке Beautiful Soup в Python!
Установка, запуск и настройка Python-библиотеки Beautiful Soup
- Начнём с установки Beautiful Soup на ваш компьютер. Для этого выполните следующую команду в командной строке или терминале:
- Теперь установите парсер: он понадобится для извлечения данных из HTML-документов. В руководстве предлагается использовать библиотеку-парсер lxml , следовательно, выполните установочную команду:
- Пришло время устанавливать библиотеку requests . Для этого выполните следующую команду в командной строке или терминале:
Наконец-то настройка окружения завершена — можно приступать к программированию!
Раздел 1: Скрейпинг одной страницы
Руководство бережно проведёт вас через каждую строчку кода, необходимого для создания вашего первого скрейпера веб-сайтов. Полный код вы найдете в самом конце статьи. Давайте начнем!
Импорт библиотек
Для скрейпинга нам пригодятся библиотеки BeautifulSoup и request , поэтому импортируем их в программу с помощью двух строчек кода:
Получение HTML-содержимого веб-сайта
Теперь, в образовательных целях, давайте получим все данные сайта, содержащего сотни страниц информации о фильмах; начнём со скрейпинга первой страницы, а затем уже разберёмся со скрейпингом множества страниц одновременно.
Наконец, воспользуемся парсером lxml для получения “супа” — объекта, содержащего все данные во вложенной структуре, которая понадобится нам в работе позднее:
Теперь, когда у нас уже есть объект soup , доступ к HTML в читабельном формате легко получается с помощью функции .prettify() . Несмотря на то, что HTML в текстовом редакторе также пригоден для ручного поиска конкретных его элементов, гораздо лучше сразу перейти к HTML-коду необходимого нам элемента страницы: в следующем шаге мы как раз это сделаем.
Анализ веб-сайта и его HTML-разметки
Важным шагом перед тем, как перейти к написанию кода, является анализ веб-сайта, скрейпинг которого производится, и полученного HTML-кода, ради нахождения самого лучшего подхода к решению задачи. Ниже приведен скриншот страницы описания фильма, по которому видно, что элементами, текст которых нужно получить, являются название фильма и реплики из него:
Movie Title — название фильма, Transcript — это диалоги из фильма
Теперь необходимо разобраться, как получить HTML только этих двух нужных нам элементов; выполните следующие действия:
- Перейдите на веб-страницу с диалогами из выбранного вами фильма.
- Наведите курсор на название фильма или его диалоги, а затем щелкните правой кнопкой мыши: появится меню, в котором выберите пункт “Исследовать”, чтобы открыть исходный код страницы сразу на нужном месте.
Ниже приведена уменьшенная версия HTML-кода, полученного после нажатия на пункт меню “Исследовать”. В дальнейшем в качестве справочника используется именно эта HTML-разметка, полезная при определении местоположения элементов в следующем шаге руководства.
Поиск HTML-элемента с помощью Beautiful Soup
Найти конкретный HTML-элемент в объекте, полученном с помощью Beautiful Soup — проще простого: нужно всего-то применить метод .find() к созданному ранее объекту из переменной soup .
В качестве примера давайте найдем блок, содержащий название фильма, описание и диалоги; нужный блок находится внутри тега article и обозначен классом main-article . Доступ к данному блоку осуществляется с помощью одной-единственной строчки кода:
Теперь давайте найдем название фильма и список реплик. Название фильма находится внутри тега h1 и не обозначено никаким классом, что никак не помешает нам его найти; после нахождения нужного элемента, было бы неплохо получить из него текст, используя метод .get_text() :
Список реплик из фильма расположен внутри тега div и обозначен классом full-script . В таком случае, чтобы получить текст, нужно изменить параметры по умолчанию в методе .get_text() . Во-первых, устанавливаем настройку strip=True , чтобы удалить все лишние пробелы. Затем добавим пробел в качестве разделителя separator="" , чтобы пробел ставился после каждой новой строки, то есть, после каждого нового символа перехода на новую строку \n :
На данный момент скрейпинг данных с одной страницы успешно завершён. Выведите в консоль или терминал значения переменных title и transcript , чтобы убедиться в корректности собственного кода на Python.
Экспорт данных в txt-файл
Скорее всего, ради возможности дальнейшего использования только что полученных в результате успешного скрейпинга данных, вы захотите куда-то их сохранить: например, экспортировать данные в формат .csv , .json или какой-либо другой; в данном примере извлеченные данные сохраняются в файле формата .txt :
При экспорте данных пригодится ключевое слово with , как показано в приведенном ниже коде:
Имейте в виду, что в примере при установке названия фильма в качестве имени файла используется f-string , известная как “форматируемая строка”.
После выполнения кода в вашем рабочем каталоге должен появиться файл в формате .txt .
Теперь, когда вы успешно выполнили скрейпинг данных с одной страницы, вы готовы приступать к скрейпингу сразу нескольких страниц!
Раздел 2: Скрейпинг нескольких страниц
Ниже представлен скриншот первой страницы сайта с диалогами из фильмов: сайт предоставляет аж 1 234 такие страницы, на каждой из которых размещено около 30-ти фильмов:
Pages — список страниц сайта, List of Movie Transctipts — список фильмов
Во второй части руководства вы узнаете, как скрейпить несколько ссылок, получая атрибут href для каждой из них. Во-первых, понадобится изменить веб-сайт для скрейпинга с используемого в первом примере на приведённый выше.
Новая переменная с идентификатором website , содержащая ссылку на веб-сайт, оформляется следующим образом:
Вы можете заметить в коде примера ещё одну новую переменную с идентификатором root — она пригодится позже.
Получение атрибута href
Сейчас вы узнаете, как получить атрибут href сразу для всех 30-ти фильмов, перечисленных на одной странице: для начала выберите любое название фильма из блока “список фильмов” на скриншоте выше.
Теперь необходимо получить HTML-разметку страницы. Каждый из HTML-тегов <a></a> относится к определенному названию фильма, причем ссылочный тег <a></a> выбранного вами фильма должен быть выделен синим цветом, как показано на скриншоте:
Теперь давайте найдем все ссылочные теги <a></a> на странице со списком фильмов.
Одновременное нахождение нескольких HTML-элементов с помощью Beautiful Soup.
Для нахождения нескольких элементов в Beautiful Soup пригодится специальный метод .find_all() с параметром-настройкой href=True : данный метод позволяет удобно и быстро извлекать ссылки, соответствующие каждой из страниц с диалогами:
Извлечь ссылки из href можно с помощью добавления указания на атрибут [‘href’] к выражению выше; однако метод .find_all() возвращает список, а не строки, поэтому придется получать атрибут href по одному внутри обходного цикла:
Теперь было бы неплохо создать свой список из ссылок в нужном формате, в чём нам поможет списковое включение, также известное как генератор списка:
При выводе списка ссылок на экран с помощью функции print() , вы увидите все те ссылки, веб-страницы которых планируется скрейпить. В следующем шаге руководства мы как раз реализуем скрейпинг каждой из них.
Переход по каждой из необходимых ссылок
Для получения диалогов фильмов по каждой из полученных на предыдущем этапе ссылок, выполним те же шаги, что и для одной ссылки ранее, но на этот раз воспользуемся циклом for , повторив таким образом все действия по нескольку раз:
Веб-скарпинг - это автоматизированный процесс сбора данных с сайта.
Интернет – является центром всей информации на Земле, к сожалению, многая информация не является правдивой. Множество дисциплин, таких как : data science, business intelligence стараются искать истинную информацию и получать из неё пользу для бизнеса.
В данном гайде мы научимся:
- Парсить веб-сайт используя string методы и обычные выражения
- Парсить используя HTML parser
- Взаимодействовать с формами и другими компонентами сайта
Сбор информации с веб-сайта
Повторим ещё раз, веб-скрапинг - это автоматизированный сбор данных с сайтов. Но некоторые сайты запрещают парсить их данные при помощи того инструмента, который мы разработаем с вами в нынешнем гайде. Сайты могут запрещать парсить свои данные по след. Причинам:
Ваш первый Web scraper
Первый пакет, который мы используем, называется urlib. Он поможет нам работать с url. Данный модуль содержит urlopen() его нужно импортировать.
Далее присваиваем переменной url адрес в формате String.
Для того чтобы открыть данный сайт в python:
Теперь вы можете вывести данные переменной, чтобы увидеть контент сайта.
И когда у вас есть 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.
Давайте на примере разберёмся.
Прежде всего, советуем установить промежуток, чтобы сайт успевал перезагружаться. Используйте time.sleep(5) - 5 секунд.
Когда вы запустите программу, вы сразу увидите первый результат, который будет выведен на консоль. Далее будет перерыв в 10 секунд и всё повторится.
После 4 циклов программа остановится.
Используя такую технику, вы сможете собирать данные сайта в реальном времени, но будьте осторожны, слишком частые запросы буду подозрительны для сайта. Иначе ваш ip будет заблокирован и не будет возможности зайти на него.
Так же возможно сломать сервер, на котором хостится сайт, поэтому советуем читать "Правила пользования" (Terms of use)
Заключение
Python уникальный инструмент для множества задач. В данном уроке мы научились собирать информацию с сайта и переводить его в текст.
Только не забывайте, не все хотят делиться информацией в интернете. Всегда читайте Правила пользования, уважайте других контент-мейкеров.
Читайте также: