CoderCastrov logo
CoderCastrov
Регулярные выражения

Как разбирать HTML с помощью регулярных выражений

Как разбирать HTML с помощью регулярных выражений
просмотров
6 мин чтение
#Регулярные выражения

Регулярные выражения или regex могут помочь вам извлекать данные с легкостью. В этом руководстве мы рассмотрим, как регулярные выражения могут помочь вам извлечь огромное количество данных из HTML. Это руководство предназначено для всех, независимо от того, являетесь ли вы начинающим или опытным программистом.

Что вы узнаете из этой статьи?

  • Как можно использовать регулярные выражения в Python?
  • Как создавать шаблоны.

Я предполагаю, что вы уже установили Python 3.x на свой компьютер. Если нет, то пожалуйста, установите его отсюда (https://www.python.org/downloads/).

Приходите, давайте исследуем искусство разбора HTML с помощью Python и Regex!

Что такое регулярное выражение?

Регулярное выражение или regex - это последовательность символов, которая формирует шаблон поиска, который может использоваться для сопоставления строк. Это очень мощный инструмент, который может использоваться для обработки текста, извлечения данных и т. д. Он поддерживается практически каждым языком, включая Python, JavaScript, Java и т. д. У него отличная поддержка сообщества, что делает поиск и сопоставление с использованием Regex очень простым.

Существует пять типов регулярных выражений:

Вот как regex может использоваться для извлечения данных.


Пример

Предположим, у нас есть следующий текст.

text = "У меня есть кошка и ловец. Кошка милая."

Наша задача - найти все вхождения слова "кошка" в данной строке текста.

Мы собираемся выполнить эту задачу с использованием библиотеки re в Python.

В этом случае шаблон будет r'\bкошка\b'. Давайте разберем его по шагам.

Python-код

import re

text = "У меня есть кошка и ловец. Кошка милая."
pattern = r'\bкошка\b'

matches = re.findall(pattern, text)

print(type(matches))

В этом примере мы использовали функцию re.findall() из модуля re в Python, чтобы найти все совпадения с шаблоном регулярного выражения \bкошка\b в строке text. Функция вернула список с совпадающим словом "кошка" в качестве результата.

Вывод будет выглядеть следующим образом.

['кошка', 'кошка']

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

Парсинг HTML с помощью регулярных выражений

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

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

  • [requests](https://pypi.org/project/requests/) - С помощью этой библиотеки мы установим HTTP-соединение с целевой страницей. Она поможет нам скачать HTML-код с страницы.
  • [re](https://docs.python.org/3/library/re.html) - С помощью этой библиотеки мы можем применять шаблоны регулярных выражений к строке.

Что мы собираемся парсить?

Всегда лучше заранее решить, что именно мы хотим извлечь с веб-сайта.

Мы собираемся извлечь две вещи с этой страницы.

Давайте скачаем данные

Я сделаю GET-запрос на целевой веб-сайт, чтобы скачать все данные HTML с веб-сайта. Для этого я буду использовать библиотеку requests.

import requests
import re

l=[]
o={}

# Отправляем GET-запрос на веб-сайт
target_url = 'http://books.toscrape.com/'
response = requests.get(target_url)

# Извлекаем HTML-контент из ответа
html_content = response.text

Вот что мы сделали в приведенном выше коде.

  • Сначала мы загрузили библиотеки requests и re.
  • Затем объявлены пустой список l и объект o.
  • Затем был объявлен целевой URL.
  • Был сделан HTTP GET-запрос с использованием библиотеки requests.
  • Весь HTML-контент сохраняется в переменной html_content.

Разберем данные с помощью регулярных выражений

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

Название хранится внутри тега h3. Затем внутри него находится тег a, который содержит название. Таким образом, шаблон для названия должен выглядеть следующим образом.

title_pattern = r'<h3><a.*?>(.*?)<\/a><\/h3>'

Я знаю, что вы, возможно, задаетесь вопросом, как я создал этот шаблон, верно? Позвольте мне объяснить вам этот шаблон, разобрав его на части.

  • <h3>: Это строка, которая соответствует открывающему тегу <h3> в HTML-контенте.
  • <a.*?>: Эта часть шаблона соответствует тегу <a> с любыми дополнительными атрибутами, которые могут присутствовать между открывающим тегом <a> и закрывающим >. .*? - это не жадный квантификатор, который соответствует нулю или более символам в не жадном (минимальном) режиме, что означает, что он будет соответствовать наименьшему количеству символов.
  • (.*?): Эта часть шаблона с помощью скобок захватывает текст внутри тегов <a>. .*? внутри скобок - это не жадный квантификатор, который захватывает любые символы (кроме символа новой строки) в не жадном (минимальном) режиме.
  • <\/a>: Это строка, которая соответствует закрывающему тегу </a> в HTML-контенте.
  • <\/h3>: Это строка, которая соответствует закрывающему тегу </h3> в HTML-контенте.

Таким образом, title_pattern предназначен для сопоставления всего HTML-элемента для названия книги, включая открывающие и закрывающие теги <h3>, тег <a> с любыми атрибутами и текст внутри тегов <a>, который представляет собой название книги. Захваченный текст внутри скобок (.*?) затем используется для извлечения фактического названия книги с помощью функции re.findall() в Python.

Теперь давайте перейдем к цене книги.

Цена хранится внутри тега p с классом price_color. Поэтому нам нужно создать шаблон, который начинается с <p class=”price_color”> и заканчивается </p>.

price_pattern = r'<p class="price_color">(.*?)<\/p>'

Этот шаблон довольно простой по сравнению с предыдущим. Но позвольте мне еще раз разобрать его для вас.

  • <p class="price_color">: Это строка, которая соответствует открывающему тегу <p> с атрибутом class="price_color", который представляет собой HTML-элемент, содержащий цену книги.
  • (.*?): Эта часть шаблона с помощью скобок захватывает текст внутри тегов <p>. .*? внутри скобок - это не жадный квантификатор, который захватывает любые символы (кроме символа новой строки) в не жадном (минимальном) режиме.
  • <\/p>: Это строка, которая соответствует закрывающему тегу </p> в HTML-контенте.

Таким образом, price_pattern предназначен для сопоставления всего HTML-элемента для цены книги, включая открывающий тег <p> с атрибутом class="price_color", текст внутри тегов <p>, который представляет собой цену книги, и закрывающий тег </p>. Захваченный текст внутри скобок (.*?) затем используется для извлечения фактической цены книги с помощью функции re.findall() в Python.

import requests
import re

l=[]
o={}

# Отправляем GET-запрос на веб-сайт
target_url = 'http://books.toscrape.com/'
response = requests.get(target_url)

# Извлекаем HTML-контент из ответа
html_content = response.text

# Определяем шаблоны регулярных выражений для названия и цены
title_pattern = r'<h3><a.*?>(.*?)<\/a><\/h3>'
price_pattern = r'<p class="price_color">(.*?)<\/p>'

# Находим все соответствия шаблонам названия и цены в HTML-контенте
titles = re.findall(title_pattern, html_content)
prices = re.findall(price_pattern, html_content)

Поскольку переменные titles и prices являются списками, нам нужно выполнить цикл for, чтобы извлечь соответствующие названия и цены и сохранить их внутри списка l.

for i in range(len(titles)):
    o["Title"]=titles[i]
    o["Price"]=prices[i]
    l.append(o)
    o={}


print(l)

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

import requests
import re

l=[]
o={}

# Отправить GET-запрос на веб-сайт
target_url = 'http://books.toscrape.com/'
response = requests.get(target_url)

# Извлечь HTML-контент из ответа
html_content = response.text

# Определить шаблоны регулярных выражений для заголовка и цены
title_pattern = r'<h3><a.*?>(.*?)<\/a><\/h3>'
price_pattern = r'<p class="price_color">(.*?)<\/p>'

# Найти все совпадения шаблонов заголовка и цены в HTML-контенте
titles = re.findall(title_pattern, html_content)
prices = re.findall(price_pattern, html_content)


for i in range(len(titles)):
    o["Заголовок"]=titles[i]
    o["Цена"]=prices[i]
    l.append(o)
    o={}


print(l)

Заключение

В этом руководстве мы узнали, как быстро разбирать сложные данные HTML с использованием регулярных выражений без использования библиотек парсинга, таких как Beautiful Soup или lxml. В начале вам может быть немного сложно понять регулярные выражения, но как только вы начнете практиковаться, все станет очень удобным.

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

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

Дополнительные ресурсы

Вот несколько дополнительных ресурсов, которые могут быть полезны во время вашего путешествия по парсингу: