L’analyseur BeautifulSoup 3.1 fonctionne beaucoup trop facilement
-
19-08-2019 - |
Question
J'avais du mal à analyser du code HTML louche avec BeautifulSoup. Il s'avère que le HTMLParser utilisé dans les versions plus récentes est moins tolérant que le SGMLParser utilisé précédemment.
Est-ce que BeautifulSoup a une sorte de mode débogage? J'essaie de trouver un moyen d'arrêter le borking avec du code HTML que je charge depuis un site Web désagréable:
<HTML>
<HEAD>
<TITLE>Title</TITLE>
<HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
</HEAD>
<BODY>
...
...
</BODY>
</HTML>
BeautifulSoup abandonne après la <HTTP-EQUIV...>
balise
In [1]: print BeautifulSoup(c).prettify()
<html>
<head>
<title>
Title
</title>
</head>
</html>
Le problème est clairement la balise HTTP-EQUIV, qui est vraiment une balise très malformée <META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
. Évidemment, je dois spécifier ceci comme fermeture automatique, mais peu importe ce que je spécifie, je ne peux pas le réparer:
In [2]: print BeautifulSoup(c,selfClosingTags=['http-equiv',
'http-equiv="pragma"']).prettify()
<html>
<head>
<title>
Title
</title>
</head>
</html>
Existe-t-il un mode de débogage détaillé dans lequel BeautifulSoup me dira ce qu’il fait, afin que je puisse comprendre ce qu’il considère comme le nom de la balise dans ce cas?
La solution
Votre problème doit être autre chose. ça marche bien pour moi:
In [1]: import BeautifulSoup
In [2]: c = """<HTML>
...: <HEAD>
...: <TITLE>Title</TITLE>
...: <HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
...: </HEAD>
...: <BODY>
...: ...
...: ...
...: </BODY>
...: </HTML>
...: """
In [3]: print BeautifulSoup.BeautifulSoup(c).prettify()
<html>
<head>
<title>
Title
</title>
<http-equiv>
</http-equiv>
</head>
<body>
...
...
</body>
</html>
In [4]:
Ceci est Python 2.5.2 avec BeautifulSoup 3.0.7a & # 8212; c'est peut-être différent dans les versions plus anciennes / plus récentes? C’est exactement le genre de soupe que BeautifulSoup gère si joliment. Je doute donc qu’elle ait été modifiée à un moment donné & # 8230; Y a-t-il autre chose à la structure que vous n'avez pas mentionnée dans le problème?
Autres conseils
Des problèmes avec Beautiful Soup 3.1.0? vous le recommande utilisez l’analyseur de html5lib comme solution de rechange.
#!/usr/bin/env python
from html5lib import HTMLParser, treebuilders
parser = HTMLParser(tree=treebuilders.getTreeBuilder("beautifulsoup"))
c = """<HTML>
<HEAD>
<TITLE>Title</TITLE>
<HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
</HEAD>
<BODY>
...
...
</BODY>
</HTML>"""
soup = parser.parse(c)
print soup.prettify()
Sortie:
<html>
<head>
<title>
Title
</title>
</head>
<body>
<http-equiv="pragma" content="NO-CACHE">
...
...
</http-equiv="pragma">
</body>
</html>
La sortie montre que html5lib n'a pas résolu le problème dans ce cas.
Essayez lxml (et son module html). En dépit de son nom, il est également destiné à l’analyse et au grattage de HTML. C'est beaucoup, beaucoup plus rapide que BeautifulSoup, et il gère même & "Cassé &"; HTML mieux que BeautifulSoup. Il a aussi une API de compatibilité pour BeautifulSoup si vous ne voulez pas apprendre l’API lxml.
Il n'y a plus aucune raison d'utiliser BeautifulSoup, sauf si vous êtes sur Google App Engine ou sur quelque chose où tout ce qui n'est pas purement Python n'est pas autorisé.