Non, BeautifulSoup, à lui seul, ne prend pas en charge les expressions XPath.
Une bibliothèque alternative, lxml , prend en charge XPath 1.0. Il a un mode compatible BeautifulSoup où il essaiera d'analyser le HTML cassé comme le fait Soup. Cependant, l' analyseur HTML lxml par défaut fait tout aussi bien un travail d'analyse du HTML cassé, et je pense qu'il est plus rapide.
Une fois que vous avez analysé votre document dans une arborescence lxml, vous pouvez utiliser la .xpath()
méthode pour rechercher des éléments.
try:
# Python 2
from urllib2 import urlopen
except ImportError:
from urllib.request import urlopen
from lxml import etree
url = "http://www.example.com/servlet/av/ResultTemplate=AVResult.html"
response = urlopen(url)
htmlparser = etree.HTMLParser()
tree = etree.parse(response, htmlparser)
tree.xpath(xpathselector)
Il existe également un module dédiélxml.html()
avec des fonctionnalités supplémentaires.
Notez que dans l'exemple ci-dessus, j'ai passé l' response
objet directement à lxml
, car il est plus efficace de lire l'analyseur directement à partir du flux que de lire d'abord la réponse dans une grande chaîne. Pour faire de même avec la requests
bibliothèque, vous souhaitez définir stream=True
et transmettre l' response.raw
objet après avoir activé la décompression transparente du transport :
import lxml.html
import requests
url = "http://www.example.com/servlet/av/ResultTemplate=AVResult.html"
response = requests.get(url, stream=True)
response.raw.decode_content = True
tree = lxml.html.parse(response.raw)
Le support du sélecteur CSS peut vous intéresser ; la CSSSelector
classe traduit les instructions CSS en expressions XPath, ce td.empformbody
qui facilite grandement votre recherche :
from lxml.cssselect import CSSSelector
td_empformbody = CSSSelector('td.empformbody')
for elem in td_empformbody(tree):
# Do something with these table cells.
La boucle est bouclée : BeautifulSoup lui - même prend en charge le sélecteur CSS très complet :
for cell in soup.select('table#foobar td.empformbody'):
# Do something with these table cells.
Je peux confirmer qu'il n'y a pas de support XPath dans Beautiful Soup.
la source
Comme d'autres l'ont dit, BeautifulSoup ne prend pas en charge xpath. Il existe probablement plusieurs façons d'obtenir quelque chose à partir d'un xpath, notamment en utilisant Selenium. Cependant, voici une solution qui fonctionne en Python 2 ou 3:
J'ai utilisé cette référence.
la source
urllib2
utilisation de la bibliothèque en Python 3urllib.request
?BeautifulSoup a une fonction nommée findNext à partir de l'élément enfant en cours, donc:
Le code ci-dessus peut imiter le xpath suivant:
la source
J'ai cherché dans leurs documents et il semble qu'il n'y ait pas d'option xpath. De plus, comme vous pouvez le voir ici sur une question similaire sur SO, l'OP demande une traduction de xpath vers BeautifulSoup, donc ma conclusion serait - non, il n'y a pas d'analyse xpath disponible.
la source
lorsque vous utilisez lxml tout simple:
mais lorsque vous utilisez BeautifulSoup BS4 tout simple aussi:
essayez cette magie:
comme vous le voyez, cela ne prend pas en charge les sous-balises, je supprime donc la partie "/ @ href"
la source
select()
est pour les sélecteurs CSS, ce n'est pas du tout XPath. comme vous le voyez, cela ne prend pas en charge les sous-balises. Bien que je ne sois pas sûr que ce soit vrai à l'époque, ce n'est certainement pas le cas maintenant.Peut-être que vous pouvez essayer ce qui suit sans XPath
la source
Ci-dessus utilisé la combinaison de l'objet Soup avec lxml et on peut extraire la valeur en utilisant xpath
la source
Il s'agit d'un fil assez ancien, mais il existe maintenant une solution de contournement, qui n'était peut-être pas dans BeautifulSoup à l'époque.
Voici un exemple de ce que j'ai fait. J'utilise le module "requests" pour lire un flux RSS et obtenir son contenu texte dans une variable appelée "rss_text". Avec cela, je l'exécute via BeautifulSoup, recherche le xpath / rss / channel / title et récupère son contenu. Ce n'est pas exactement XPath dans toute sa splendeur (jokers, chemins multiples, etc.), mais si vous avez juste un chemin de base que vous souhaitez localiser, cela fonctionne.
la source