web-dev-qa-db-fra.com

Définir lxml comme analyseur BeautifulSoup par défaut

Je travaille sur un projet de grattage Web et j'ai rencontré des problèmes de vitesse. Pour essayer de le réparer, je veux utiliser lxml au lieu de html.parser comme analyseur de BeautifulSoup. J'ai pu faire ça:

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

mais je ne veux pas avoir à taper à plusieurs reprises 'lxml' chaque fois que j'appelle BeautifulSoup. Existe-t-il un moyen de définir quel analyseur utiliser une fois au début de mon programme?

19
Adam Hammes

Selon la page de documentation Spécification de l'analyseur à utiliser :

Le premier argument du constructeur BeautifulSoup est une chaîne ou un descripteur de fichier ouvert, le balisage que vous souhaitez analyser. Le deuxième argument est de savoir comment vous souhaitez que le balisage soit analysé.

Si vous ne spécifiez rien, vous obtiendrez le meilleur analyseur HTML installé. Beautiful Soup classe l'analyseur de lxml comme étant le meilleur, puis celui de html5lib, puis celui de Python intégré.

En d'autres termes, simplement installer lxml dans le même environnement python en fait un analyseur par défaut.

Notez cependant que la mention explicite d'un analyseur est considérée comme une approche basée sur les meilleures pratiques. Il y a différences entre les analyseurs qui peuvent entraîner des erreurs subtiles qui seraient difficiles à déboguer si vous laissez BeautifulSoup choisir le meilleur analyseur par lui-même. Vous devez également vous rappeler que vous devez avoir lxml installé. Et, si vous ne l'auriez pas installé, vous ne le remarqueriez même pas - BeautifulSoup obtiendrait simplement le prochain analyseur disponible sans lancer d'erreurs.

Si vous ne voulez toujours pas spécifier explicitement l'analyseur, notez au moins pour vous-même ou pour les autres personnes qui utiliseraient le code que vous avez écrit dans le README/documentation du projet, et répertoriez lxml dans votre projet exigences aux côtés de beautifulsoup4.

En outre: "Explicit vaut mieux qu'implicite."

16
alecxe

Jetez évidemment un œil à la réponse acceptée en premier. C'est assez bon, et quant à cette technicité:

mais je ne veux pas avoir à taper à plusieurs reprises "lxml" chaque fois que j'appelle BeautifulSoup. Existe-t-il un moyen de définir quel analyseur utiliser une fois au début de mon programme?

Si j'ai bien compris votre question, je peux penser à deux approches qui vous feront économiser quelques touches: - Définir une fonction wrapper, ou - Créer une fonction partielle.

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

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

Ou si vous avez envie de vous montrer ...

import bs4
from functools import partial
bs_parse = partial(bs4.BeautifulSoup, features='lxml')
# ...
html = ...
bs_parse(html)
8
Leonid