2016-03-22 12 views
2

Ich kratze Titel, Beschreibungen, Links und die Namen der Menschen aus einer Vielzahl von divs, die die gleiche Struktur folgen. Ich benutze BeautifulSoup, und ich bin in der Lage, alles aus dem ersten div zu kratzen. Allerdings habe ich Probleme, aus meiner langen Liste von divs zu scannen und die Daten in einem portablen Format wie CSV oder JSON zu bekommen.BeautifulSoup scraping Informationen aus mehreren divs mit Loops in JSON

Wie kann ich jedes Element aus meiner langen Liste von divs schaben, und diese Informationen in JSON-Objekte zusammen für jedes mp3 speichern?

Die divs wie folgt aussehen:

<div class="audioBoxWrap clearBoth"> 
    <h3>Title 1</h3> 
    <p>Description 1</p> 
    <div class="info" style="line-height: 1px; height: 1px; font-size: 1px;"></div> 
    <div class="audioBox" style="display: none;"> 
     stuff 
    </div> 
    <div> [ <a href="link1.mp3">Right-click to download</a>] </div> 
</div> 
<div class="audioBoxWrap clearBoth"> 
    <h3>Title 2</h3> 
    <p>Description 2</p> 
    <div class="info" style="line-height: 1px; height: 1px; font-size: 1px;"></div> 
    <div class="audioBox" style="display: none;"> 
     stuff 
    </div> 
    <div> [ <a href="link2.mp3">Right-click to download</a>] </div> 
</div> 

Ich habe herausgefunden, wie aus dem ersten div kratzen, aber ich kann nicht die Informationen für jedes div greifen. Zum Beispiel spuckt mein Code unten die h3 für das erste div immer und immer wieder aus.

Ich weiß, dass ich eine Python-Liste für Titel, Beschreibungen usw. erstellen kann, aber wie behalte ich die Metadatenstruktur wie JSON, so dass title1, link1 und description1 zusammen bleiben, sowie die Informationen von title2.

with open ('soup.html', 'r') as myfile: 
    html_doc = myfile.read() 

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

    audio_div = soup.find_all('div', {'class':"audioBoxWrap clearBoth"}) 

    print len(audio_div) 
    #create dictionary for storing scraped data. I don't know how to store the values for each mp3 separately. 

    for i in audio_div: 
     print soup.find('h3').text 

Ich möchte meine JSON so etwas wie folgt aussehen:

{ 
    "podcasts":[ 
     { 
     "title":"title1", 
     "description":"description1", 
     "link":"link1" 
     }, 
     { 
     "title":"title2", 
     "description":"description2", 
     "link":"link2" 
     } 
    ] 
} 

Antwort

3

Iterate über jede Spur und kontextspezifische Suche machen:

from pprint import pprint 

from bs4 import BeautifulSoup 

data = """ 
<div> 
    <div class="audioBoxWrap clearBoth"> 
     <h3>Title 1</h3> 
     <p>Description 1</p> 
     <div class="info" style="line-height: 1px; height: 1px; font-size: 1px;"></div> 
     <div class="audioBox" style="display: none;"> 
      stuff 
     </div> 
     <div> [ <a href="link1.mp3">Right-click to download</a>] </div> 
    </div> 
    <div class="audioBoxWrap clearBoth"> 
     <h3>Title 2</h3> 
     <p>Description 2</p> 
     <div class="info" style="line-height: 1px; height: 1px; font-size: 1px;"></div> 
     <div class="audioBox" style="display: none;"> 
      stuff 
     </div> 
     <div> [ <a href="link2.mp3">Right-click to download</a>] </div> 
    </div> 
</div>""" 

soup = BeautifulSoup(data, "html.parser") 

tracks = soup.find_all('div', {'class':"audioBoxWrap clearBoth"}) 
result = { 
    "podcasts": [ 
     { 
      "title": track.h3.get_text(strip=True), 
      "description": track.p.get_text(strip=True), 
      "link": track.a["href"] 
     } 
     for track in tracks 
    ] 
} 
pprint(result) 

Drucke:

{'podcasts': [{'description': 'Description 1', 
       'link': 'link1.mp3', 
       'title': 'Title 1'}, 
       {'description': 'Description 2', 
       'link': 'link2.mp3', 
       'title': 'Title 2'}]} 
+0

Thank Du hast funktioniert! Außer, warum hat das Ergebnis Beschreibung, Link und Titel in einer anderen Reihenfolge als in Ergebnis =? Auch meine gedruckten Beschreibungen nehmen viele Zeilen im Terminal auf (Beschreibungen sind eigentlich ganze Absätze). Ist das nur ein Merkmal von pprint und nicht der eigentliche Inhalt der Anführungszeichen in der Beschreibung? – moglido

+0

@moglido sicher, das ist nur ein Wörterbuch - es hat keine vordefinierte Reihenfolge. – alecxe