Extraire des données avec beautifulSoup

Le problème exposé dans ce sujet a été résolu.

Bonsoir chers amis je travail avec python3.4 et beautifulsoup . Je voudrais savoir s’il est possible d’extraire deux balises d’un coup suivant leur ordre et s’il était

possible de recuperer le texte contenu dans toutes les balises imbriquées. Je m’explique.

<h1>Économie</h1>

<p>du texte ici relatif au premier h1<b>le texte contenu ici<em>important</em></b></p>

<h1>Sport</h1>

<p>du texte ici relatif au deuxième h1</p>

<p>du texte ici relatif au deuxième h1</p>

Ici telle que les données sont disposées on a un lien entre un h1 avec un p, donc si je prend d’abord les balise p ensuite les balises h1 je vais avoir une erreur, je ne vais pas savoir si tel p est relié avec tel h1, D’où ma question de savoir si on ne peut pas recuperer deux balises a la fois selon leur disposition.

<p>du texte ici relatif au premier h1<b>le texte contenu ici<em>important</em></b></p>

recuperer le texte: du texte ici relatif au premier h1 le texte contenu ici important.

J’ai fait des recherches mais je n’ai rien trouver de convainquant.

Merci pour vos réponses.

Salut,

Pour ton premier problème, regarde du côté de .next_sibling. Ca te donnera donc un truc du genre :

1
2
3
for title in soup.find_all('h1'):
    if title.next_sibling is not None and title.next_sibling.name == 'p':
        pass # bonjour, je suis un paragraphe qui suit un h1

Pour le second, tu as .get_text() qui te retourne une string contenant tout le texte d’un élément et de ses enfants :

1
2
soup = BeautifulSoup('<a>foo<b>bar</b>baz</a>', 'html.parser')
soup.find('a').get_text() # => 'foobarbaz'

J’arrive après la bataille.

Juste pour préciser que BeatifulSoup ne mérite pas du tout sa popularité, et qu’il peut être avantageusement remplacé par lxml qui est à la fois plus simple (car il utilise la syntaxe xpath standard) et beaucoup plus efficace.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
>>> from lxml import html
>>> tree = html.fromstring(data)
>>> for title in tree.xpath('//h1'):
...     print(title.text_content())
...     content = title.getnext()
...     print(content.text_content())
...     print()
...     
... 
Économie
du texte ici relatif au premier h1le texte contenu iciimportant

Sport
du texte ici relatif au deuxième h1
+1 -0

Juste pour préciser que BeatifulSoup ne mérite pas du tout sa popularité, et qu’il peut être avantageusement remplacé par lxml qui est à la fois plus simple (car il utilise la syntaxe xpath standard) et beaucoup plus efficace.

nohar

Tu peux dire à BeautifulSoup d’utiliser lxml pour le parsing, si tu cherches l’efficacité.

Le problème résolu par BeautifulSoup que lxml.html ne résout pas aussi bien, c’est le HTML mal formé. Donc à part si t’as la main sur le HTML que tu parses, auquel cas t’as souvent mieux à faire que le parser, il vaut mieux prévenir les problèmes d’un HTML cassé (genre une balise pas fermée en plein milieu, ou autre bêtise) et utiliser BeautifulSoup au lieu de lxml.

Dans un cas général de scraping, on peut pas faire confiance au HTML pour qu’il soit bien formé. Je pense que c’est pour ça que BeautifulSoup mérite sa popularité.

+0 -0

Le problème résolu par BeautifulSoup que lxml.html ne résout pas aussi bien, c’est le HTML mal formé.

C’est ce que je croyais aussi il y a quelques années. C’est comme ça que BS "se vend"…

Sauf qu’au boulot, dans un soft qui parse plusieurs dizaines de milliers de pages html par seconde (et des pages de la vraie vie, hein…), je ne suis jamais tombé sur un doc qui mette en défaut lxml.html.

Du coup je pense que c’est une légende urbaine. Ce que je crois (mais n’ai jamais vérifié), c’est que BeautifulSoup est antérieur à lxml, et qu’ils ont ajouté a posteriori le support de lxml en backend le jour où le module html a été rajouté dans lxml, tout simplement parce que ça permettait de faire un x12 en perfs sans pour autant péter la codebase qui reposait sur BS.

De plus, en termes d’interface je préfère très largement l’expressivité (et l’efficacité) des xpaths aux méthodes bizarres de BeautifulSoup.

Le seul truc que fait BS et pas lxml, c’est UnicodeDammit, mais si on n’a pas accès aux headers HTTP (ou que ceux-ci mentent), un coup de cchardet puis un réencodage préalable au parsing suffit à s’en affranchir.

Et tout ça (cchardet et lxml) a de surcroît le bon goût de libérer le GIL en travaillant, ce qui permet de paralléliser les opérations en les exécutant dans des threads séparés. :)

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte