Установите lxml в качестве парсера BeautifulSoup по умолчанию

Я работаю над проектом по очистке веб-страниц и столкнулся с проблемами со скоростью. Чтобы попытаться это исправить, я хочу использовать lxml вместо html.parser в качестве парсера BeautifulSoup. Я смог сделать это:

soup = bs4.BeautifulSoup(html, 'lxml')

но я не хочу постоянно вводить 'lxml' каждый раз, когда я вызываю BeautifulSoup. Есть ли способ установить, какой синтаксический анализатор использовать один раз в начале моей программы?


person Adam Hammes    schedule 06.01.2015    source источник
comment
lxml является значением по умолчанию в bs4, если у вас установлено lxml. Так что, если только вы не работаете с BeautifulSoup3...   -  person roippi    schedule 06.01.2015
comment
Я использую bs4, но я не знал, как проверить, какой парсер я сейчас использую. Благодарю вас!   -  person Adam Hammes    schedule 06.01.2015
comment
Относится к stackoverflow.com/questions/33511544, содержащему другие подробности.   -  person bufh    schedule 30.06.2020


Ответы (2)


Согласно Указание анализатора для использования страница документации:

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

Если вы ничего не укажете, вы получите лучший из установленных парсеров HTML. Beautiful Soup оценивает парсер lxml как лучший, затем парсер html5lib, а затем встроенный парсер Python.

Другими словами, просто установив lxml в той же среде Python, вы сделаете его парсером по умолчанию.

Однако обратите внимание, что явное указание синтаксического анализатора считается оптимальным подходом. Существуют различия между синтаксическими анализаторами, которые могут привести к тонким ошибки, которые было бы трудно отлаживать, если вы позволяете BeautifulSoup самому выбирать лучший синтаксический анализатор. Вы также должны помнить, что вам необходимо установить lxml. И, если бы он у вас не был установлен, вы бы его даже не заметили - BeautifulSoup просто получил бы следующий доступный парсер, не выдавая никаких ошибок.

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

Кроме того: "Явное лучше, чем неявное".

person alecxe    schedule 06.01.2015
comment
Обратите внимание, что в bs4 версии 4.5.1 при указании синтаксического анализатора 'lxml' и отсутствии его установки bs4 выдает ошибку: bs4.FeatureNotFound: Не удалось найти построитель дерева с запрошенными функциями: lxml . Вам нужно установить библиотеку парсера? - person glexey; 16.12.2016

Очевидно, сначала взгляните на принятый ответ. Это довольно хорошо, и что касается этой техники:

но я не хочу постоянно вводить «lxml» каждый раз, когда я вызываю BeautifulSoup. Есть ли способ установить, какой синтаксический анализатор использовать один раз в начале моей программы?

Если я правильно понял ваш вопрос, я могу придумать два подхода, которые сэкономят вам несколько нажатий клавиш: - Определите функцию-оболочку или - Создайте частичную функцию.

# V1 - define a wrapper function - most straight-forward.
import bs4

def bs_parse(html):
    return bs4.BeautifulSoup(html, 'lxml')
# ...
html = ...
bs_parse(html)

Или, если вам хочется покрасоваться...

import bs4
from functools import partial
bs_parse = partial(bs4.BeautifulSoup, features='lxml')
# ...
html = ...
bs_parse(html)
person Leonid    schedule 27.01.2017
comment
Можете ли вы объяснить, как работает partial? Есть ли какие-либо преимущества в использовании его по сравнению с функцией-оболочкой? - person r3robertson; 02.08.2017
comment
@r3robertson Здесь есть хорошая документация по частичным функциям: docs.python.org /2/library/functools.html#functools.partial Мне кажется, что partial работает медленнее и сложнее внутри по сравнению с оберткой, но как только он реализован, его довольно легко использовать . Частичные функции чисты из-за отсутствия лучшего слова с математической точки зрения. В других языках это есть, и некоторые считают это хорошим использованием функционального программирования, но вы платите цену с точки зрения скорости и дополнительного импорта. Я до сих пор использую частичные функции, потому что это весело. - person Leonid; 02.08.2017
comment
@ r3robertson Кстати, частичные функции не должны создавать дополнительных накладных расходов при использовании определенных скомпилированных языков, для которых производительность является приоритетом, но Python не является одним из таких языков. Однако C++ vittorioromeo.info/index/blog/cpp17_curry.html - person Leonid; 05.11.2020