2017-09-21 9 views
1

je le code HTML suivant:Obtenir la première instance de texte pour l'élément parent dans BeautifulSoup

<div> 


    <h5>Item1</h5> 
    $14.00<br> 
    <br> 

    <h5>Item2</h5> 
    $16.29 (Shop Rite)<br> 
    $15.49 (Costco)<br> 
    <br> 

    <h5>Item3</h5> 
    ... 
</div> 

Je suis en train d'organiser cette information dans une liste en fonction du nombre d'éléments, comme par exemple:

+--------+--------------------+ 
| Item1 | $14.00 (BJs)  | 
| Item2 | $16.29 (Shop Rite) | 
| Item2 | $15.49 (Costco) | 
+--------+--------------------+ 

Je voudrais quelque chose de similaire à ce qui suit:

Items = [] 
if (BS.find('h5', text="Item1")): 
    for content in BS.find('h5', text="Item1").parent: 
    Price = BS.find('h5', text="Item1").parent.content[0] 
    Items.append("Item1", Price) 

Mon objectif principal est d'être en mesure d'obtenir le texte de Eparés individuellement par les balises <br>, puis stockés dans une liste appelée Items mais je ne suis pas sûr de savoir comment parcourir chaque balise <br> de la balise en fonction de la balise <h5>.

Répondre

1

Je vous suggère de collecter les données que vous collectez dans un objet de type dictionnaire plutôt que dans une liste, de sorte que vous puissiez associer un nombre de prix à chaque texte d'en-tête. J'ai utilisé un defaultdict avec un type list.

Trouvez d'abord la collection des éléments h5. Ensuite, trouvez la collection de frères et soeurs pour chacun d'eux. Mais notez que les deuxième et troisième éléments h5 sont les frères et soeurs de la première, par exemple, ce qui signifie que, dans le traitement des frères et soeurs h5 nous voulons arrêter quand nous rencontrons un autreh5. Nous break quand nous voyons cela. De la même manière, lorsque nous rencontrons un élément br, nous l'ignorons; nous continue et continuons avec le prochain frère. Puis aussi, si le frère est vide mais pour les espaces blancs, nous l'ignorons également.

Enfin, un élément qui réussit ces tests est ajouté au dictionnaire.

>>> import bs4 
>>> soup = bs4.BeautifulSoup(open('temp.htm').read(), 'lxml') 
>>> from collections import defaultdict 
>>> info = defaultdict(list) 
>>> for h5 in soup.findAll('h5'): 
...  for item in h5.next_siblings: 
...   if item.name == 'br': 
...    continue 
...   if item.name == 'h5': 
...    break 
...   if not item.strip(): 
...    continue 
...   info[h5.text].append(item.strip()) 
... 

Nous pouvons afficher le contenu du dictionnaire de cette façon. Je vous laisse le soin de le formater correctement.

>>> info 
defaultdict(<class 'list'>, {'Item1': ['$14.00'], 'Item3': [], 'Item2': ['$16.29 (Shop Rite)', '$15.49 (Costco)']}) 
>>> for item in info: 
...  for price in info[item]: 
...   item, price 
...   
('Item1', '$14.00') 
('Item2', '$16.29 (Shop Rite)') 
('Item2', '$15.49 (Costco)')