Реализация веб-парсинга в Python с помощью BeautifulSoup
Существует два основных способа извлечения данных с веб-сайта:
- Использовать API сайта (если он существует). Например, у Facebook есть Facebook Graph API, который позволяет извлекать данные, размещенные на Facebook.
- Получить доступ к HTML-странице сайта и извлечь из нее полезную информацию/данные. Эта техника называется веб-парсинг, веб-сборкой или извлечением данных из веб-страницы.
В этой статье рассматриваются шаги, связанные с веб-парсингом, на примере реализации фреймворка для веб-парсинга на языке Python под названием Beautiful Soup. Шаги, выполняемые при веб-парсинге:
- Отправьте HTTP-запрос на URL веб-страницы, к которой вы хотите получить доступ. Сервер отвечает на запрос, возвращая HTML-содержимое веб-страницы. Для решения этой задачи мы будем использовать стороннюю HTTP-библиотеку python-requests.
- После того как мы получили доступ к HTML-содержимому, нам остается разобрать данные. Поскольку большая часть HTML-данных является вложенной, мы не можем извлечь данные просто путем обработки строк. Необходим парсер, способный создать вложенную/деревянную структуру HTML-данных. Существует множество библиотек парсеров HTML, но наиболее продвинутой из них является html5lib.
- Теперь нам необходимо выполнить навигацию и поиск по созданному нами дереву разбора, т.е. обход дерева. Для этой задачи мы будем использовать еще одну стороннюю библиотеку Python - Beautiful Soup. Это библиотека Python для извлечения данных из HTML- и XML-файлов.
Шаг 1: Установка необходимых сторонних библиотек
Наиболее простым способом установки внешних библиотек в python является использование pip. pip - это система управления пакетами, которая используется для установки и управления пакетами программ, написанных на Python. Все, что вам нужно сделать, это:
pip install requests
pip install html5lib
pip install bs4
Другой способ - загрузить их вручную по этим ссылкам:
requests
html5lib
beautifulsoup4

Шаг 2: Получение доступа к HTML-содержимому веб-страницы
импорт запросов
URL = "https://www.geeksforgeeks.org/data-structures/"
r = requests.get(URL)
print(r.content)
Попробуем разобраться в этом фрагменте кода.
- Прежде всего, импортируйте библиотеку requests.
- Затем укажите URL-адрес веб-страницы, с которой необходимо произвести сканирование.
- Отправьте HTTP-запрос на указанный URL и сохраните ответ от сервера в объекте response с именем r.
- Теперь в качестве print r.content получите необработанное HTML-содержимое веб-страницы. Оно имеет тип 'string'.
headers = {'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246"}
# Здесь указан агент пользователя для браузера Edge на windows 10. Пользовательский агент браузера можно узнать по приведенной выше ссылке.
r = requests.get(url=URL, headers=headers)
print(r.content)
Шаг 3: Разбор HTML-содержимого
#Это не будет выполняться в онлайн IDE
import requests
from bs4 import BeautifulSoup
URL = "http://www.values.com/inspirational-quotes"
r = requests.get(URL)
soup = BeautifulSoup(r.content, 'html5lib') # If this line causes an error, run 'pip install html5lib' or install html5lib
print(soup.prettify())
Очень приятным моментом в библиотеке BeautifulSoup является то, что она построена поверх библиотек разбора HTML, таких как html5lib, lxml, html.parser и т.д. Таким образом, объект BeautifulSoup и указание библиотеки парсера могут быть созданы одновременно. В приведенном примере,
soup = BeautifulSoup(r.content, 'html5lib')
Мы создаем объект BeautifulSoup, передавая ему два аргумента:
- r.content: Это исходный HTML-контент.
- html5lib: указывается парсер HTML, который мы хотим использовать.
Теперь выводится soup.prettify(), который дает визуальное представление дерева разбора, созданного из исходного HTML-содержимого.
Шаг 4: Поиск и навигация по дереву разбора
Теперь мы хотим извлечь некоторые полезные данные из HTML-содержимого. Объект soup содержит все данные во вложенной структуре, которые могут быть извлечены программным путем. В нашем примере мы извлекаем веб-страницу, состоящую из некоторых цитат. Поэтому мы хотим создать программу для сохранения этих цитат (и всей необходимой информации о них).
#Python-программа для сканирования веб-сайта
#и сохранения цитат с сайта
import requests
from bs4 import BeautifulSoup
import csv
URL = "http://www.values.com/inspirational-quotes"
r = requests.get(URL)
soup = BeautifulSoup(r.content, 'html5lib')
quotes=[] # a list to store quotes
table = soup.find('div', attrs = {'id':'all_quotes'})
for row in table.findAll('div',
attrs = {'class':'col-6 col-lg-3 text-center margin-30px-bottom sm-margin-30px-top'}):
quote = {}
quote['theme'] = row.h5.text
quote['url'] = row.a['href']
quote['img'] = row.img['src']
quote['lines'] = row.img['alt'].split(" #")[0]
quote['author'] = row.img['alt'].split(" #")[1]
quotes.append(quote)
filename = 'inspirational_quotes.csv'
with open(filename, 'w', newline='') as f:
w = csv.DictWriter(f,['theme','url','img','lines','author'])
w.writeheader()
for quote in quotes:
w.writerow(quote)
Замечено, что все кавычки находятся внутри контейнера div, id которого 'all_quotes'. Поэтому мы находим этот элемент div (в приведенном выше коде он обозначен как table) с помощью метода find():
table = soup.find('div', attrs = {'id':'all_quotes'})

Первым аргументом является HTML-тег, по которому производится поиск, а вторым - элемент словарного типа для указания дополнительных атрибутов, связанных с этим тегом. Метод find() возвращает первый подходящий элемент. Вы можете попробовать напечатать table.prettify(), <\/strong>чтобы получить представление о том, что делает эта часть кода.
Теперь в элементе таблицы можно заметить, что каждая цитата находится внутри контейнера div, класс которого - quote. Поэтому мы перебираем все div-контейнеры, класс которых равен quote. Здесь мы используем метод findAll(), который по аргументам похож на метод find, но возвращает список всех совпадающих элементов. Теперь каждая цитата итерируется с помощью переменной row. Для лучшего понимания приведен пример HTML-содержимого строки: Implementing Web Scraping in Python with Beautiful Soup <\/strong>Теперь рассмотрим этот фрагмент кода:
for row in table.find_all_next('div', attrs = {'class': 'col-6 col-lg-3 text-center margin-30px-bottom sm-margin-30px-top'}):
quote = {}
quote['theme'] = row.h5.text
quote['url'] = row.a['href']
quote['img'] = row.img['src']
quote['lines'] = row.img['alt'].split(" #")[0]
quote['author'] = row.img['alt'].split(" #")[1]
quotes.append(quote)
Мы создаем словарь для сохранения всей информации о цитате. Доступ к вложенной структуре можно получить с помощью точечной нотации. Для доступа к тексту внутри HTML-элемента мы используем .text :
quote['theme'] = row.h5.text
Мы можем добавлять, удалять, изменять и получать доступ к атрибутам тега. Для этого тег рассматривается как словарь:
quote['url'] = row.a['href'].
Наконец, все кавычки добавляются в список под названием quotes.
Наконец, мы хотим сохранить все наши данные в некотором CSV-файле.
filename = 'inspirational_quotes.csv'
with open(filename, 'w', newline='') as f:
w = csv.DictWriter(f,['theme','url','img','lines','author'])
w.writeheader()
for quote in quotes:
w.writerow(quote)
Здесь мы создаем CSV-файл inspirational_quotes.csv и сохраняем в нем все цитаты для дальнейшего использования.
Итак, это был простой пример создания веб-парсера на языке Python. Далее вы можете попробовать создать любой другой сайт по вашему выбору.


