2015-10-22 7 views
6

Ich versuche, eine Seite zu kratzen BeatifulSoup mitScrape nur der Text innerhalb eines HTML-Elements, das eine Klasse hat, mit schöner Suppe

import urllib2 
from bs4 import BeautifulSoup 

url='http://www.xpn.org/playlists/xpn-playlist' 
page = urllib2.urlopen(url) 

soup = BeautifulSoup(page.read()) 

for link in soup.find_all("li", class_="song"): 
    print link 

Das Problem ist der Text Ich mag würde, wird nicht zurückkehren eingeschlossen in einem eigenen hTML-Tag

<li class="song"> <a href="/default.htm" onclick="return clickreturnvalue() 
" onmouseout="delayhidemenu()" onmouseover="dropdownmenu(this, event, menu1, 
'100px','Death Vessel','Mandan Dink','Stay Close')">Buy</a> 
Chuck Ragan - Rotterdam - Folkadelphia Session</li> 

Was ich Chuck Ragan - Rotterdam - Folkadelphia Session

Bonuspunkte zurückkehren wollen: die zurückgegebenen Daten des Formats Künstlers/Lied/A lbum. Was wäre die richtige Datenstruktur, um diese Informationen zu speichern und zu bearbeiten?

Antwort

1

Versuchen Sie so etwas wie:

for link in soup.find_all("li", class_="song"): 
    print link.text 

Ausgang:

Buy Chuck Ragan - Rotterdam - Folkadelphia Session 

Sicher, wenn Sie Buy entfernen möchten, können Sie slice wie folgt verwenden:

for link in soup.find_all("li", class_="song"): 
    print link.text.strip()[5:] 

Der Ausgang ist :


Wenn Sie diese Zeichenfolge in einer Liste speichern möchten:

[i.strip() for i in link.text.strip()[5:].split('-')] 

Ausgang:

['Chuck Ragan', 'Rotterdam', 'Folkadelphia Session'] 

Für weitere Informationen können Sie die document überprüfen.

+0

Thanks man! Wie genau funktioniert [5:]? –

+1

Das sind die ersten 5 Zeichen entfernen. siehe [diese Frage] (http://stackoverflow.com/questions/509211/explain-pythons-slice-notation). –

+0

Und über * Was wäre die richtige Datenstruktur zum Speichern und Bearbeiten dieser Informationen? *, Vielleicht Datenbank verwenden? –

0

Sie könnten so etwas verwenden.

for l in soup.find_all("li", class_="song"): 
    album = l.text.split("-")[2] 
    song = l.text.split("-")[1] 
    artist = l.text.split("-")[0].split(" ")[1] 
1

Hier ist ein anderer Weg! (Unter der Annahme li hat 3 Kinder Wenn nicht, [2] zu [1] ändern.):

>>> html = '''<li class="song"> <a href="/default.htm" onclick="return clickreturnvalue() 
... " onmouseout="delayhidemenu()" onmouseover="dropdownmenu(this, event, menu1, 
... '100px','Death Vessel','Mandan Dink','Stay Close')">Buy</a> 
... Chuck Ragan - Rotterdam - Folkadelphia Session</li>''' 

>>> from bs4 import BeautifulSoup as bs 
>>> all_li = soup.findAll('li', class_='song') 
>>> for li in all_li: 
...  text = list(li.children)[2] 
...  artist, song, album = text.split('-') 
...  print artist, song, album 
Chuck Ragan Rotterdam Folkadelphia Session 
+0

Versuchte diese Lösung aber bekam einen Fehler '----> 9 all_li = Suppe.findall ('li', Klasse _ = 'Lied') '' TypeError: 'NoneType' -Objekt kann nicht aufgerufen werden ' –

+0

Beachten Sie, dass 'soup.findAll()' und 'soup.findall()' verschiedene Funktionen sind! Der, nach dem wir suchen, ist 'supp.findAll()' nicht der, den du ausprobiert hast :-) –

+0

Ah! Vielen Dank!! –

0

** ein named tuple für die Lagerung am Ende mit **

from bs4 import BeautifulSoup 
import urllib2 
from collections import namedtuple 

url='http://www.xpn.org/playlists/xpn-playlist' 
page = urllib2.urlopen(url) 


soup = BeautifulSoup(page.read()) 

songs=[] 
Song = namedtuple("Song", "artist name album") 
for link in soup.find_all("li", class_="song"): 
    song = Song._make(link.text.strip()[12:].split(" - ")) 
    songs.append(song) 

for song in songs: 
    print(song.artist, song.name, song.album) 
Verwandte Themen