Задайте 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