Допустим, необходимо использовать BeautifulSoup4, чтобы посмотреть на теги <a>
в HTML-документе. При этом, тратится время и оперативная память для разбора всего документа, и только после этого происходит поиск тегов <a>
. Намного быстрее изначально игнорировать все, что не является тегом <a>
. Класс SoupStrainer
позволяет выбрать, какие части входящего HTML-документ разбирать. Нужно только создать объект SoupStrainer
и передать его в конструктор BeautifulSoup()
в качестве аргумента parse_only
.
Обратите внимание, что класс SoupStrainer
не будет работать, если использовать парсер html5lib
. Если использовать html5lib
, будет разобран весь документ, независимо от обстоятельств. Это потому что html5lib
постоянно переставляет части дерева разбора в процессе работы, и если какая-то часть документа не попала в дерево разбора, все рухнет.
Класс SoupStrainer
принимает те же аргументы, что и типичный метод из раздела "Методы .find_all()
и .find()
модуля BeautifulSoup4": name
, attrs
, string
и **kwargs
.
HTML-документ, который будем разбирать:
<html><head><title>The Dormouse's story</title></head> <body> <p class="title"><b>The Dormouse's story</b></p> <p class="story">Once upon a time there were three little sisters; and their names were <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>, <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; and they lived at the bottom of a well.</p> <p class="story">...</p>
Смотрим на HTML-документ, разобранный объектом SoupStrainer
:
name
.>>> from bs4 import SoupStrainer, BeautifulSoup # используем `name` для создания объекта `SoupStrainer` >>> a_tags = SoupStrainer("a") # передаем объект `a_tags` аргументу `parse_only` >>> soup = BeautifulSoup(html_doc, "html.parser", parse_only=a_tags) >>> print(soup.prettify()) # <a class="sister" href="http://example.com/elsie" id="link1"> # Elsie # </a> # <a class="sister" href="http://example.com/lacie" id="link2"> # Lacie # </a> # <a class="sister" href="http://example.com/tillie" id="link3"> # Tillie # </a>
**kwargs
.# используем `**kwargs` для создания объекта `SoupStrainer` >>> id_link2 = SoupStrainer(id="link2") # передаем объект `id_link2` аргументу `parse_only` >>> soup = BeautifulSoup(html_doc, "html.parser", parse_only=id_link2) >>> print(soup.prettify()) # <a class="sister" href="http://example.com/lacie" id="link2"> # Lacie # </a>
attrs
.# используем `attrs` для создания объекта `SoupStrainer` >>> class_id = SoupStrainer(attrs={'class': 'sister', 'id':'link1'}) # передаем объект `class_id` аргументу `parse_only` >>> soup = BeautifulSoup(html_doc, "html.parser", parse_only=class_id) >>> print(soup.prettify()) # <a class="sister" href="http://example.com/elsie" id="link1"> # Elsie # </a>
Также, можно передать объект SoupStrainer
в любой из методов, описанных в разделе "Методы .find_all()
и .find()
модуля BeautifulSoup4".
>>> from bs4 import SoupStrainer, BeautifulSoup >>> root = BeautifulSoup(html_doc, 'html.parser') >>> id_link2 = SoupStrainer(id="link2") >>> root.find_all(id_link2) # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]