Примеры парсинга HTML сайта с BeautifulSoup в Python

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

Содержание статьи

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

Установка BeautifulSoup в Python

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

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

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

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

Пример HTML-кода страницы

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

<!DOCTYPE html>

<html>

    <head>

        <title>Header</title>

        <meta charset="utf-8">                  

    </head>

    <body>

        <h2>Operating systems</h2>

        <ul id="mylist" style="width:150px">

            <li>Solaris</li>

            <li>FreeBSD</li>

            <li>Debian</li>                      

            <li>NetBSD</li>          

            <li>Windows</li>        

        </ul>

        <p>

          FreeBSD is an advanced computer operating system used to

          power modern servers, desktops, and embedded platforms.

        </p>

        <p>

          Debian is a Unix-like computer operating system that is

          composed entirely of free software.

        </p>        

    </body>    

</html>

BeautifulSoup простой пример парсинга HTML

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

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    print(soup.h2)

    print(soup.head)

    print(soup.li)

Код в данном примере позволяет вывести HTML-код трех тегов.

from bs4 import BeautifulSoup

Здесь производится импорт класса BeautifulSoup из модуля bs4. Таким образом, BeautifulSoup является главным рабочим классом.

with open("index.html", "r") as f:

    contents = f.read()

Открывается файл index.html и производится чтение его содержимого при помощи метода read().

soup = BeautifulSoup(contents, 'lxml')

Создается объект BeautifulSoup. Данные передаются конструктору. Вторая опция уточняет объект парсинга.

print(soup.h2)

print(soup.head)

Далее выводится HTML-код следующих двух тегов: h2 и head.

В примере много раз используются элементы li, однако выводится только первый из них.

$ ./simple.py

<h2>Operating systems</h2>

<head>

<title>Header</title>

<meta charset="utf-8"/>

</head>

<li>Solaris</li>

Это результат вывода.

BeautifulSoup теги, атрибуты name и text

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

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    print("HTML: {0}, name: {1}, text: {2}".format(soup.h2,

        soup.h2.name, soup.h2.text))

Код в примере позволяет вывести HTML-код, название и текст h2 тега.

$ ./tags_names.py

HTML: <h2>Operating systems</h2>, name: h2, text: Operating systems

Это результат вывода.

Метод recursiveChildGenerator() позволяет перебрать содержимое HTML-документа.

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    for child in soup.recursiveChildGenerator():

        if child.name:

            print(child.name)

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

$ ./traverse_tree.py

html

head

title

meta

body

h2

ul

li

li

li

li

li

p

p

Данные теги являются частью рассматриваемого HTML-документа.

BeautifulSoup атрибут children

При помощи атрибута children можно вывести все дочерние теги.

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    root = soup.html

    root_childs = [e.name for e in root.children if e.name is not None]

    print(root_childs)

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

$ ./get_children.py

['head', 'body']

Следовательно, у тегов html есть два дочерних элемента: head и body.

BeautifulSoup атрибут descendants

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

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    root = soup.body

    root_childs = [e.name for e in root.descendants if e.name is not None]

    print(root_childs)

Данный пример позволяет найти всех потомков главного тега body.

$ ./get_descendants.py

['h2', 'ul', 'li', 'li', 'li', 'li', 'li', 'p', 'p']

Перечисленные выше теги являются потомками главного тега body.

BeautifulSoup и веб-скрапинг HTML

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


#!/usr/bin/python3

from bs4 import BeautifulSoup

import requests as req

resp = req.get("http://www.something.com")

soup = BeautifulSoup(resp.text, 'lxml')

print(soup.title)

print(soup.title.text)

print(soup.title.parent)

Данный пример извлекает название рассматриваемой веб-страницы. Здесь также выводится имя ее родителя.

resp = req.get("http://www.something.com")

soup = BeautifulSoup(resp.text, 'lxml')

Здесь мы получаем информацию о веб-странице.

print(soup.title)

print(soup.title.text)

print(soup.title.parent)

Код выше помогает вывести HTML-код заголовка, его текст, а также HTML-код его родителя.

$ ./scraping.py

<title>Something.</title>

Something.

<head><title>Something.</title></head>

Это результат вывода.

BeautifulSoup метод prettify()

При помощи метода prettify() можно добиться того, чтобы HTML-код выглядел аккуратнее.

#!/usr/bin/python3

from bs4 import BeautifulSoup

import requests as req

resp = req.get("http://www.something.com")

soup = BeautifulSoup(resp.text, 'lxml')

print(soup.prettify())

Таким образом, мы оптимизируем HTML-код простой веб-страницы.

$ ./prettify.py

<html>

<head>

  <title>

   Something.

  </title>

</head>

<body>

  Something.

</body>

</html>

Это результат вывода.

BeautifulSoup метод find(), поиск элементов по id

При помощи метода find() можно найти элементы страницы, используя различные опорные параметры, id в том числе.

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    #print(soup.find("ul", attrs={ "id" : "mylist"}))

    print(soup.find("ul", id="mylist"))

Код в примере находит тег ul, у которого id mylist. Строка в комментарии является альтернативным способом выполнить то же самое задание.

BeautifulSoup метод find_all() поиск всех тегов в HTML

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

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    for tag in soup.find_all("li"):

        print("{0}: {1}".format(tag.name, tag.text))

Код в примере позволяет найти и вывести на экран все li теги.

$ ./find_all.py

li: Solaris

li: FreeBSD

li: Debian

li: NetBSD

Это результат вывода.

Метод find_all() также при поиске использует список из названий тегов.

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    tags = soup.find_all(['h2', 'p'])

    for tag in tags:

        print(" ".join(tag.text.split()))

В данном примере показано, как найти все h2 и p элементы, после чего вывести их содержимое на экран.

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

#!/usr/bin/python3

from bs4 import BeautifulSoup

def myfun(tag):

    return tag.is_empty_element

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    tags = soup.find_all(myfun)

    print(tags)

Данный пример выводит пустые элементы.

$ ./find_by_fun.py

[<meta charset="utf-8"/>]

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

Также можно найти запрашиваемые элементы, используя регулярные выражения.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

#!/usr/bin/python3

import re

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    strings = soup.find_all(string=re.compile('BSD'))

    for txt in strings:

        print(" ".join(txt.split()))

В данном примере выводится содержимое элементов, в которых есть строка с символами ‘BSD’.

$ ./regex.py

FreeBSD

NetBSD

FreeBSD is an advanced computer operating system used to power modern servers, desktops, and embedded platforms.

Это результат вывода.

BeautifulSoup методы select() и select_one() CSS селекторы

При помощи методов select() и select_one() для нахождения запрашиваемых элементов можно использовать некоторые CSS селекторы.

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    print(soup.select("li:nth-of-type(3)"))

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

$ ./select_nth_tag.py

<li>Debian</li>

Данный элемент li является третьим в списке.

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

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    print(soup.select_one("#mylist"))

В данном примере выводятся элементы, которых есть id под названием mylist.

BeautifulSoup метод append() добавление нового HTML-тега

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    newtag = soup.new_tag('li')

    newtag.string='OpenBSD'

    ultag = soup.ul

    ultag.append(newtag)

    print(ultag.prettify())

В примере выше показано, как в HTML-документ добавить новый тег li.

newtag = soup.new_tag('li')

newtag.string='OpenBSD'

Для начала, требуется создать новый тег при помощи метода new_tag().

Далее создается сноска на тег ul.

Затем созданный ранее тег li добавляется к тегу ul.

Таким образом, тег ul выводится аккуратно отформатированным.

BeautifulSoup метод insert() вставка HTML-тега

Метод insert() позволяет вставить тег в определенно выбранное место.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    newtag = soup.new_tag('li')

    newtag.string='OpenBSD'

    ultag = soup.ul

    ultag.insert(2, newtag)

    print(ultag.prettify())

В примере показано, как поставить тег li на третью позицию в выбранном ul теге.

BeautifulSoup метод replace_with() замена текста в теге

Метод replace_with() заменяет содержимое выбранного элемента.

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    tag = soup.find(text="Windows")

    tag.replace_with("OpenBSD")

    print(soup.ul.prettify())

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

BeautifulSoup метод decompose() удаление HTML-тега

Метод decompose() удаляет определенный тег из структуры документа и уничтожает его.

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    ptag2 = soup.select_one("p:nth-of-type(2)")

    ptag2.decompose()

    print(soup.body.prettify())

В данном примере показано, как удалить второй элемент p в документе.

В данном руководстве было показано, как использовать библиотеку BeautifulSoup в Python.

Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.

E-mail: vasile.buldumac@ati.utm.md

Образование
Universitatea Tehnică a Moldovei (utm.md)

  • 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
  • 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»