Веб-скраппинг с помощью BeautifulSoup — пошаговое руководство

beautifulsoup парсинг python

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

Причина использования python в этом руководстве довольно очевидна: python очень гибкий и имеет большую поддержку сообщества. Даже если вы новичок, пытающийся научиться веб-скрейпингу с помощью python, эта статья будет очень полезна для вас. Это длинное руководство, поэтому пристегните ремни и давайте начнем.

Прежде чем приступить к веб-скрейпингу в Python, давайте поймем важность HTTP заголовков при парсинге любой веб-страницы. Мы подробно рассмотрим HTTP заголовки. Возможно, я ошибаюсь, но когда я начинал программировать, меня очень пугали HTTP заголовки. Но вскоре я понял, что использовать заголовки при составлении HTTP-запросов очень просто.

HTTP-заголовки (необходимое для веб-скрейпинга в python)

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

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

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

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

HTTP Заголовки — это своего рода индикаторы метаданных о том, из чего состоит ответ или запрос. Чтобы понять это, позвольте мне классифицировать заголовки. Итак, в основном их можно разделить на четыре различные категории.

  • Заголовки запроса;
  • Заголовки ответа;
  • Заголовки полезной нагрузки (payload);
  • Заголовки представления (определенного типа, Content-Type)

Это не означает, что заголовок запроса не может быть заголовком ответа и наоборот. Давайте разберемся, что на самом деле означает каждый из этих заголовков.

Заголовки запроса

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

Примерами заголовков запроса являются:

  • Host: www.python-scripts.com
  • User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
  • Referer: localhost
  • Connection: close
  • Accept-Language: ru
  • Accept-Encoding; gzip

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

Из приведенного выше списка заголовков-образцов, Host и User-Agent содержат информацию о том, кто посылает запрос.

Accept-Language говорит серверу, что это язык, на котором я могу понять ваш ответ, и аналогично Accept-Encoding говорит серверу, что даже если у вас сжатые данные, я могу их понять.

Заголовки ответа

Они похожи на заголовки запроса, но передача происходит в обратном порядке. На самом деле, эти заголовки посылаются сервером клиенту. Они объясняют клиенту, что делать с ответом. Он предоставляет дополнительную информацию об отправленных данных.

Пример заголовков ответа:

  • Connection: keep-alive
  • Date: Mon, 08 Nov 2022
  • Server: nginx
  • Content-Type: text/html
  • Transfer-Encoding: chunked
  • Etag: W/”0815”

Etag — это заголовок ответа, который используется для указания версии и кэша. Date сообщает клиенту дату, когда ответ был отправлен от сервера к клиенту. Но опять же Content-Type или Content-Encoding — это заголовки представления, которые мы рассмотрим чуть позже.

Заголовки представления

Заголовки представления указывают на тип переданных данных. Данные, отправленные с сервера к клиенту, могут быть в любом формате, например JSON, HTML, XML, chunked (если размер данных огромен) и т. д. Сервер также сообщает клиенту о диапазоне содержимого.

Примеры заголовков представления:

  • Content-Type: text/html
  • Content-Encoding: gzip
  • Content-Length: 3523
  • Content-Range: bytes 50–1000/*
  • Content-Location: /docs/fo.xml

Content-Location сообщает клиенту об альтернативном расположении ресурса или данных, которые доступны клиенту для получения информации. Это может быть URL, где хранится данный конкретный ресурс.

Помимо этих заголовков, могут быть и другие заголовки, такие как Trailer, Transfer-Encoding, Etag, if-Not-Match, Authorizations и т.д.

Теперь, что если вы разрабатываете API и хотите определить свои собственные заголовки? Можете ли вы это сделать? Вы совершенно спокойно можете это сделать. Таким же образом, как вы определяете структуру запроса и ответа вашего API, вы можете реализовать собственные заголовки, которые будете принимать вы или сервер.

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

Библиотека BeautifulSoup на примерах

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

BeautifulSoup — это Python библиотека для разбора HTML и XML документов. Она часто используется для веб-скрейпинга. BeautifulSoup преобразует сложный HTML-документ в сложное дерево объектов Python, таких как тег, навигационная строка или комментарий.

Установка BeautifulSoup

Мы используем команду pip для установки необходимых модулей.

Нам необходимо установить модуль lxml, который используется BeautifulSoup.

BeautifulSoup устанавливается с помощью вышеуказанной команды.

HTML файл с которым мы будем работать

В примерах мы будем использовать следующий HTML-файл:

Открываем HTML файл через BeautifulSoup

В первом примере мы используем модуль BeautifulSoup для получения трех тегов.

Пример кода выводит HTML-код трех тегов.

Мы импортируем класс BeautifulSoup из модуля bs4. BeautifulSoup — это основной класс для выполнения парсинга по HTML документу.

Мы открываем файл index.html и читаем его содержимое с помощью метода read().

Создается объект BeautifulSoup, HTML-данные передаются конструктору. Второй параметр определяет синтаксический анализатор.

Здесь мы выводим HTML-код двух тегов: <h2> и <head>.

Имеется несколько элементов <li>, данная строка выведет первый из них.

Полученный результат после выполнения скрипта:

Приватные прокси для смены IP в библиотеке Requests

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

Как результат мы получим IP-адрес от приватных прокси которых мы купили. Есть proxy для которых не нужно указывать логин и пароль, но в случае приватных прокси — их указывать нужно.

Манипуляция тегами через BeautifulSoup

Атрибут name тега дает его название, а атрибут text — его текстовое содержание.

В приведенном примере кода выводится HTML, имя и содержимое из тега <h2>.

Полученный результат:

Обход HTML-дерева используя BeautifulSoup

С помощью метода recursiveChildGenerator мы обходим HTML-документ.

Пример пробегает по дереву документа и печатает имена всех HTML-тегов.

Полученный результат:

В HTML-документе у нас есть эти теги.

Обход дочерних элементов

С помощью атрибута children мы можем получить дочерние элементы тега.

Обход потомков элемента

С помощью атрибута descendants мы получаем всех потомков (детей всех уровней) тега.

Пример извлекает все потомки тега <body>.

Полученный результат:

Это все потомки тега <body>.

Открываем сайт для парсинга через Requests + BeautifulSoup

Requests — это простая HTTP библиотека для Python. Она предоставляет методы для доступа к веб-ресурсам через HTTP запросы.

Этот пример извлекает заголовок из простой веб-страницы. Он также выводит информацию о родительском тега <title>.

Мы получаем HTML исходный код страницы.

Мы получаем HTML-код заголовка <title>, его текст и HTML-код его родителя.

Полученный результат:

Красивое структурирование HTML кода

С помощью метода prettify мы можем «красиво» структурировать исходный HTML-код.

Полученный результат:

Поиск HTML-элементов по ID

С помощью метода find мы можем находить элементы по различным признакам, включая id элемента.

Данный пример кода находит тег ul, который имеет id mylist.

Поиск всех HTML-элементов по названию

С помощью метода find_all мы можем найти все элементы, которые соответствуют некоторым критериям.

Пример кода находит и выводит все теги li.

Метод find_all может принимать список с названиями элементов для поиска.

Пример находит все элементы <h2> и <p> и выводит их содержимое.

Метод find_all также может принимать функцию, которая определяет, какие элементы должны быть возвращены.

В примере выводятся пустые элементы.

Единственным пустым элементом в документе является <meta>.

Также можно найти элементы с помощью регулярных выражений.

Пример выводит содержимое элементов, которые содержат строку BSD.

Поиск HTML-элементов по CSS-селектору

С помощью методов select и select_one мы можем использовать некоторые селекторы CSS для поиска элементов.

В этом примере используется CSS селектор для вывода HTML кода третьего элемента <li>.

Это третий элемент <li>.

Символ # используется в CSS для выбора тегов по их id-атрибутам.

В примере выводится элемент, имеющий идентификатор mylist.

Создание и добавление тега в тело другого тега

Метод append добавляет новый тег в HTML-документ.

В этом примере добавляется новый тег <li>.

Сначала мы создаем новый тег с помощью метода new_tag.

Получаем ссылку на тег <ul>.

Мы добавляем только что созданный тег в тело тега <ul>.

Выводим содержимое тега в «красивом» оформлении HTML кода.

Вставка тега в определенном месте

Метод insert вставляет тег в заданное место.

В этом примере созданный тег <li> вставляется на третью позицию в тело тега <ul>.

Замена текста в HTML элементе

Метод replace_with заменяет текст внутри элемента.

В этом примере конкретный элемент найден с помощью метода find, а его содержимое заменено с помощью метода replace_with.

Удаление HTML элемента

Метод decompose удаляет тег из HTML-документа и уничтожает его.

В данном примере удаляется второй элемент <p>.

В этом учебнике мы работали с Python библиотекой BeautifulSoup.