Поиск по сайту:
Счастье — как здоровье, когда его не замечаешь, значит, оно есть (И. Тургенев).

Как разобрать (парсинг) HTML с помощью Python

12.02.2025
Как разобрать (парсинг) HTML с помощью Python

Парсинг — это автоматический поиск различных шаблонов (на основе заранее заданных структур) в источниках текстовых данных для извлечения конкретной информации.

Хотя парсинг — это общий термин, чаще всего он обозначает процесс сбора и анализа данных с удалённых веб-ресурсов.

В языке программирования Python можно создавать программы для анализа данных со сторонних веб-сайтов с помощью двух основных инструментов:

  • Стандартный пакет HTTP-запросов
  • Внешние библиотеки обработки HTML-разметки

 

Однако возможности обработки данных не ограничиваются только HTML-документами.

Благодаря широкому спектру внешних библиотек в Python вы можете организовать синтаксический анализ документов любой сложности, будь то произвольный текст, популярные языки разметки (например, XML) или даже редкие языки программирования.

Если подходящей библиотеки для синтаксического анализа нет, вы можете реализовать его вручную, используя низкоуровневые методы, которые Python предоставляет по умолчанию, например, простой поиск по строке или регулярные выражения. Хотя, конечно, это требует дополнительных навыков.

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

Мы запускаем все примеры из этой статьи с помощью интерпретатора Python 3.10.12 на сервере с Ubuntu 22.04 и Pip 22.0.2 в качестве менеджера пакетов.

 

Структура HTML — документа

Любой документ, написанный на HTML, состоит из двух типов тегов:

  1. Открытие: определяется с помощью символов меньше (<) и больше (>), например, <div>.
  2. Закрытие: определяется внутри символов меньше (<) и больше (>) с помощью косой черты (/), например, </div>.

 

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

  • href: Ссылка на ресурс. Например, href="https://andreyex.ru".
  • class: Класс объекта. Например., class="surface panel panel_closed".
  • id: Идентификатор объекта. Например., id="menu".

 

Каждый тег, с атрибутами или без них, является элементом (объектом) так называемого дерева DOM (объектной модели документа), которое создаётся практически любым интерпретатором (парсером) HTML.

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

Например, в браузере мы получаем доступ к элементам и их атрибутам с помощью скриптов JavaScript. В Python для этого используются отдельные библиотеки. Разница в том, что после анализа HTML-документа браузер не только создаёт дерево DOM, но и отображает его на мониторе.

<!DOCTYPE html>

<html>
    <head>
        <title>Это заголовок страницы</title>
    </head>

    <body>
        <h1>Это заголовок</h1>
        <p>Это простой текст.</p>
    </body>
</html>

 

Разметка этой страницы создана с помощью тегов в иерархической структуре без указания каких-либо атрибутов:

  • html
    • head
      • title
    • body
      • h1
      • p

 

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

Однако у реальных тегов веб-сайтов есть дополнительные атрибуты, которые определяют как конкретную функцию элемента, так и его особый стиль (описанный в отдельных файлах CSS):

<!DOCTYPE html>
<html>
    <body>
...
<ul class="nav nav-pills">
<li class="nav-item"><a class="nav-link" title="Социальные сети" href="https://andreyex.ru/">Главная</a></li>
<li class="nav-item"><a class="nav-link" title="Социальные сети" href="https://andreyex.ru/category/socialnye-seti/">Соц сети</a></li>
<li class="nav-item"><a class="nav-link" title="Учебное пособие по Linux" href="https://andreyex.ru/operacionnaya-sistema-linux/">Linux</a></li>
...
    </body>
</html>

 

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

 

Структура Анализатора HTML-данных

Веб -страницы могут быть двух типов:

  • Статический: во время загрузки и просмотра сайта HTML-разметка остаётся неизменной. Для синтаксического анализа не требуется имитировать поведение браузера.

  • Динамический: во время загрузки и просмотра сайта (одностраничного приложения, SPA) HTML-разметка изменяется с помощью JavaScript. Для синтаксического анализа требуется имитировать поведение браузера.

Читать  Как установить и использовать AIDE в Ubuntu 22.04

 

Анализировать статические веб-сайты относительно просто: после отправки удалённого запроса необходимые данные извлекаются из полученного HTML-документа.

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

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

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

Разнообразие технических реализаций современных веб-сайтов настолько велико, что их нельзя отнести к полностью статичным или полностью динамичным.

Как правило, общая информация загружается изначально, в то время как конкретная информация загружается позже.

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

В Python библиотеки (пакеты), предназначенные для анализа HTML-разметки, можно разделить на две группы:

  1. Процессоры низкого уровня: компактные, но синтаксически сложные пакеты со сложной реализацией, которые анализируют синтаксис HTML (или XML) и создают иерархическое дерево элементов.
  2. Библиотеки и фреймворки высокого уровня: большие, но синтаксически лаконичные пакеты с широким спектром функций для извлечения формализованных данных из необработанных HTML-документов. В эту группу входят не только компактные HTML-парсеры, но и полноценные системы для сбора данных. Часто эти пакеты используют низкоуровневые парсеры (процессоры) из первой группы в качестве основы для синтаксического анализа.

 

Для Python доступно несколько низкоуровневых библиотек:

  • lxml: низкоуровневый синтаксический анализатор XML, который также используется для анализа HTML. Он основан на популярной библиотеке libxml2 на языке C.
  • html5libБиблиотека Python для синтаксического анализа HTML, написанная в соответствии со спецификацией HTML, разработанной WHATWG (Рабочей группой по технологиям веб-гипертекстовых приложений), которой придерживаются все современные браузеры.

 

Однако использование библиотек высокого уровня быстрее и проще — у них более простой синтаксис и более широкий набор функций:

  • BeautifulSoup: простая, но гибкая библиотека для Python, которая позволяет анализировать HTML- и XML-документы, создавая полное дерево DOM элементов и извлекая необходимые данные.
  • Scrapy: полноценный фреймворк для анализа данных с HTML-страниц, состоящий из автономных «пауков» (веб-сканеров) с заранее заданными инструкциями.
  • Selectolax: быстрый анализатор HTML-страниц, который использует CSS-селекторы для извлечения информации из тегов.
  • Parsel: библиотека Python с особым синтаксисом селекторов, которая позволяет извлекать данные из HTML-, JSON- и XML-документов.
  • requests-html: библиотека Python, которая точно имитирует CSS-селекторы браузера, написанные на JavaScript.

 

В этой статье будут рассмотрены некоторые из этих высокоуровневых библиотек.

 

Установка менеджера пакетов pip

Мы можем установить все библиотеки синтаксического анализа (а также многие другие пакеты) в Python с помощью стандартного менеджера пакетов pip, который необходимо установить отдельно.

Во-первых, обновите список доступных репозиториев:

sudo apt update

 

Затем установите pip с помощью диспетчера пакетов APT:

sudo apt install python3-pip -y

 

Флаг -y автоматически подтверждает все запросы терминала во время установки.

Чтобы убедиться, что pip был установлен правильно, проверьте его версию:

pip3 --version

 

Читать  Создание загрузчика анимации сканирования с использованием HTML и CSS

Терминал отобразит версию pip и путь установки:

pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)

 

Как показано в этом руководстве, используется pip версии 22.0.2.

 

Установка пакета HTTP-запросов

Обычно интерпретатор Python по умолчанию включает пакет Requests, который позволяет отправлять запросы на удалённые серверы. Мы будем использовать его в примерах этого руководства.

Однако в некоторых случаях он может быть не установлен. Тогда вы можете установить requests вручную с помощью pip:

pip install requests

 

Если он уже установлен в системе, вы увидите следующее сообщение в терминале:

Requirement already satisfied: requests in /usr/lib/python3/dist-packages (2.25.1)

 

В противном случае команда добавит requests в список доступных пакетов для импорта в скрипты Python.

 

Использование BeautifulSoup

Чтобы установить BeautifulSoup версии 4, используйте pip:

pip install beautifulsoup4

 

После этого библиотека будет доступна для импорта в скрипты Python. Однако для корректной работы также требуются ранее упомянутые низкоуровневые обработчики HTML.

Сначала установите lxml:

pip install lxml

 

Затем установите html5lib:

pip install html5lib

 

В будущем вы сможете указать один из этих процессоров в качестве основного синтаксического анализатора для BeautifulSoup в своём коде на Python.

Создайте новый файл в вашем домашнем каталоге:

nano bs.py

Добавьте следующий код:

import requests
from bs4 import BeautifulSoup

# Запрос на веб-сайт 'https://andreyex.ru'
response = requests.get('https://andreyex.ru')

# Проанализируйте HTML-содержимое страницы с помощью синтаксического анализатора html5lib
page = BeautifulSoup(response.text, 'html5lib')

# Извлеките заголовок страницы
pageTitle = page.find('title')
print(pageTitle)
print(pageTitle.string)

print("")

# Извлеките все ссылки <a> на странице
pageParagraphs = page.find_all('a')

# Распечатайте содержимое первых 3-х ссылок (если они существуют).
for i, link in enumerate(pageParagraphs[:3]):
    print(link.string)

print("")

# Найдите все элементы div с классом, начинающимся на 'socials--'
social_links_containers = page.find_all('div', class_=lambda c: c and c.startswith('socials--'))

# Соберите ссылки из этих разделов
for container in social_links_containers:
    links = container.find_all('a', href=True)
    for link in links:
        href = link['href']

        # Игнорируйте ссылки, связанные с защитой электронной почты Cloudflare
        if href.startswith('/cdn-cgi/l/email-protection'):
            continue

        print(href)

 

Теперь запустите скрипт:

python bs.py

 

Это приведет к следующему выводу на консоль:

<title>AndreyEx - ИТ Блог. Администрирование серверов на основе Linux (Ubuntu, Debian, CentOS, openSUSE). Разработка сайтов на CMS WordPress</title>
AndreyEx - ИТ Блог. Администрирование серверов на основе Linux (Ubuntu, Debian, CentOS, openSUSE). Разработка сайтов на CMS WordPress

...

Конечно, вместо html5lib вы можете указать lxml:

page = BeautifulSoup(response.text, 'lxml')

 

Однако в качестве процессора лучше всего использовать библиотеку html5lib. В отличие от lxml, которая специально разработана для работы с разметкой XML, html5lib полностью поддерживает современные стандарты HTML5.

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

 

Использование Scrapy

Фреймворк Scrapy реализован более объектно-ориентированным способом. В Scrapy анализ веб-сайтов основан на трёх основных сущностях:

  • Паукеры: классы, содержащие информацию о деталях синтаксического анализа для указанных веб-сайтов, включая URL-адреса, селекторы элементов (CSS или XPath) и механизмы просмотра страниц.
  • Элементы: переменные для хранения извлечённых данных, которые представляют собой более сложные формы словарей Python со специальной внутренней структурой.
  • Конвейеры: промежуточные обработчики извлечённых данных, которые могут изменять элементы и взаимодействовать с внешним программным обеспечением (например, с базами данных).

 

Вы можете установить Scrapy через pip менеджер пакетов:

pip install scrapy

 

После этого вам нужно инициализировать проект парсера, который создаст отдельный каталог со своей собственной структурой папок и файлами конфигурации:

scrapy startproject parser

 

Читать  Как настроить серверные блоки Nginx в Ubuntu 22.04

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

cd parser

 

Проверьте содержимое текущего каталога:

ls

 

В нем есть общий конфигурационный файл и каталог с исходными файлами проекта:

parser scrapy.cfg

 

Переместить в каталог исходных файлов:

cd parser

 

Если вы проверите его содержимое:

ls

 

Вы увидите как специальные скрипты Python, каждый из которых выполняет свою функцию, так и отдельный каталог для пауков:

__init__.py items.py middlewares.py pipelines.py settings.py spiders

 

Давайте откроем файл настроек:

nano settings.py

 

По умолчанию большинство параметров закомментированы символом решётки (#). Чтобы синтаксический анализатор работал корректно, вам нужно раскомментировать некоторые из этих параметров, не изменяя значения по умолчанию, указанные в файле:

  • USER_AGENT
  • ROBOTSTXT_OBEY
  • CONCURRENT_REQUESTS
  • DOWNLOAD_DELAY
  • COOKIES_ENABLED

 

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

После этого вы можете сгенерировать нового паука:

scrapy genspider hostmanspider andreyex.ru

 

После выполнения приведённой выше команды на консоли должно появиться сообщение о создании нового паука:

Created spider ‘hostmanspider' using template 'basic' in module:
 parser.spiders.hostmanspider

 

Теперь, если вы проверите содержимое каталога spiders:

ls spiders

 

Вы увидите пустые исходные файлы для нового spider:

__init__.py  __pycache__  hostmanspider.py

 

Давайте откроем файл скрипта:

nano spiders/hostmanspider.py

 

И заполните его следующим кодом:

from pathlib import Path  # Package for working with files
import scrapy  # Пакет из фреймворка Scrapy

class HostmanSpider(scrapy.Spider):  # Класс Spider наследуется от класса Spider
        name = 'hostmanspider'  # Name of the spider

        def start_requests(self):
                urls = ["https://andreyex.ru"]
                for url in urls:
                        yield scrapy.Request(url=url, callback=self.parse)

        def parse(self, response):
                open("output", "w").close()  # Очистите содержимое "output" файла
                someFile = open("output", "a")  # Создайте (или добавьте к нему) новый файл

                dataTitle = response.css("title::text").get()  # Извлеките заголовок из ответа сервера с помощью CSS-селектора

                dataA = response.css("a").getall()  # Извлеките первые 3 ссылки из ответа сервера с помощью CSS-селектора

                someFile.write(dataTitle + "\n\n")
                for i in range(3): 
                    someFile.write(dataA[i] + "\n")
                someFile.close()

 

Теперь вы можете запустить созданный spider с помощью следующей команды:

scrapy crawl hostmanspider

 

При запуске паука в текущем каталоге будет создан выходной файл. Чтобы просмотреть содержимое этого файла, вы можете использовать:

cat output

 

Содержимое этого файла будет выглядеть примерно так:

AndreyEx - ИТ Блог. Администрирование серверов на основе Linux (Ubuntu, Debian, CentOS, openSUSE). Разработка сайтов на CMS WordPress

<a class="nav-link" title="Социальные сети" href="https://andreyex.ru/">Главная</a>
<a class="nav-link" title="Социальные сети" href="https://andreyex.ru/category/socialnye-seti/">Соц сети</a>
<a class="nav-link" title="Учебное пособие по Linux" href="https://andreyex.ru/operacionnaya-sistema-linux/">Linux</a>

 

Более подробную информацию о извлечении данных с помощью селекторов (как CSS, так и XPath) можно найти в официальной документации Scrapy.

 

Заключение

Анализ данных из удаленных источников в Python становится возможным благодаря двум основным компонентам:

  1. Пакет для отправки удаленных запросов
  2. Библиотеки для синтаксического анализа данных

 

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

В Python наиболее популярными библиотеками для синтаксического анализа статических данных являются:

  • BeautifulSoup
  • Scrapy

 

Эти инструменты, похожие на функции JavaScript (например, getElementsByClassName() с использованием селекторов CSS), позволяют извлекать данные (атрибуты и текст) из элементов дерева DOM любого HTML-документа.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (1 оценок, среднее: 4,00 из 5)
Загрузка...
Поделиться в соц. сетях:


5 1 голос
Рейтинг статьи
Подписаться
Уведомить о
guest

**ссылки nofollow

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

Это может быть вам интересно


Рекомендуемое
При работе с различными приложениями часто приходится обращаться к журналам,…

Спасибо!

Теперь редакторы в курсе.