1
votes

Vérification des enfants pour les balises dans Beautiful Soup 4 avec python

J'utilise BeautifulSoup 4 avec python pour analyser du HTML. Voici le code:

IN
[]
[]
 COURT OF {county} COUNTY
STATE OF OKLAHOMA

Le résultat est:

for child in soup.p.children:
    if isinstance(child, str):
        print(child)
    else:
        print(child.findChildren('i', recursive=False))

Tout cela a du sens. Ce que j'essaie de faire est de parcourir les résultats et si je trouve un ou un , alors faites quelque chose de différent avec eux. Lorsque j'essaye ce qui suit, cela ne fonctionne pas:

for child in soup.p.children:
    if child.find('i'):
        print(child)

L'erreur est parce que le premier enfant retourné est une chaîne et j'essaye de le rechercher pour une balise enfant et BS4 sait déjà qu'il n'y a pas d'enfants présents.

J'ai donc changé le code pour vérifier si l'enfant est une chaîne, et si c'est le cas, n'essayez pas de prendre des mesures dessus, imprimez-le simplement .

IN
 COURT OF {county} COUNTY
STATE OF OKLAHOMA

Le résultat de ce dernier code:

for child in soup.p.children:
    if isinstance(child, str):
        print(child)
    elif child.findAll('i'):
        for tag in child.findAll('i'):
            print(tag)

En parcourant les résultats, je dois pouvoir pour vérifier les balises dans le résultat, mais je n'arrive pas à comprendre comment. Je pensais que cela devrait être simple, mais je suis perplexe.

EDIT:

En réponse à jacalvo:

Si je lance

for child in soup.p.children:
    if child.findChildren('i'):
        print('italics found')

Cela échoue toujours imprimer les 2ème et 3ème lignes du code HTML

Modifier:

IN
<i>THE </i>
<b>DISTRICT</b>
 COURT OF {county} COUNTY
STATE OF OKLAHOMA

Cela a abouti à:

from bs4 import BeautifulSoup as bs
html_doc = '<p class="line-spacing-double" align="center">IN <i>THE </i><b>DISTRICT</b> COURT OF {county} COUNTY\nSTATE OF OKLAHOMA</p>'

soup = bs(html_doc, 'html.parser')
para = soup.p

for child in soup.p.children:
    print (child)


4 commentaires

Pourquoi ne pas utiliser find ('i') au lieu de findChildren ()?


p = soup.select_one ('p') puis p.select ('i, b')


jacalvo - J'avais besoin d'écrire du code (qui suce dans les commentaires) donc je vous ai répondu par une modification dans le message d'origine.


@Andrej Kesely - Cela fonctionne pour trouver les balises et , mais j'ai besoin de les parcourir toutes, pas seulement de trouver ces balises. Leur placement dans le HTML est important pour ce que je dois faire.


3 Réponses :


0
votes
    IN 
    <i>THE </i>
    <b>DISTRICT</b>
     COURT OF {county} COUNTY
    STATE OF OKLAHOMA

6 commentaires

Je vais vous répondre en éditant la question afin que je puisse publier le code que j'ai exécuté avec votre recursive = False dedans.


Je suis sur le point de recourir à l'expression régulière :) Le plus grand péché pour l'analyse HTML LOL


OMG! c'est une décision extrême à prendre ... (: peut-être que je ne comprends pas votre idée, mais j'ai mis à jour le code avec plus d'italiques et de gras et je les ai tous imprimés dans deux listes différentes afin que vous puissiez faire d'autres manipulations par la suite


Cela trouve tous les italiques et gras, mais cela ne me permet pas de parcourir le texte en tant qu'enfants. La raison pour laquelle j'ai besoin de les parcourir, c'est que je convertis en DOCX et que je dois utiliser python-docx en add_run () et cela nécessite un certain ordre par rapport à l'autre texte qui se trouve également dans le paragraphe.


Oh! J'ai eu un problème similaire lorsque j'ai créé un énorme texte riche dynamique avec worksheet.write_rich_string dans xlsxwriter ... l'ordre compte. donc, vous avez besoin d'enfants, de balises et de texte tout en faisant le processus, je suppose


J'ai ajouté tag.name et child.text pour conserver les deux éléments. voyons si ça marche



0
votes

Utilisez findChildren (), puis vérifiez le nom de l'enfant avec les conditions if.

<i>THE </i>
<b>DISTRICT</b>

Sortie:

from bs4 import BeautifulSoup as bs
html_doc = '<p class="line-spacing-double" align="center">IN <i>THE </i><b>DISTRICT</b> COURT OF {county} COUNTY\nSTATE OF OKLAHOMA</p>'

soup = bs(html_doc, 'html.parser')

for child in soup.find('p').findChildren(recursive=False) :
    if child.name=='i':
        print(child)
    if child.name=='b':
        print(child)


0 commentaires

1
votes

Est-ce un exemple de ce que vous essayez de faire comme exemple de "faire quelque chose de différent" avec des balises? Avoir un échantillon de la sortie complète souhaitée dans la question aiderait:

IN *THE* **DISTRICT** COURT OF {county} COUNTY
STATE OF OKLAHOMA

Sortie:

from bs4 import BeautifulSoup as bs

html_doc = '<p class="line-spacing-double" align="center">IN <i>THE</i> <b>DISTRICT</b> COURT OF {county} COUNTY\nSTATE OF OKLAHOMA</p>'
soup = bs(html_doc, 'html.parser')
para = soup.p

for child in para.children:
    if child.name == 'i':
        print(f'*{child.text}*',end='')
    elif child.name == 'b':
        print(f'**{child.text}**',end='')
    else:
        print(child,end='')


1 commentaires

C'est exactement ce dont j'avais besoin. Je ne pensais même pas au nom de l'enfant qui était la balise présente, mais c'est parfaitement logique avec le recul.