Schöne Suppe und Extrahieren eines Div und seines Inhalts nach ID

147
soup.find("tagName", { "id" : "articlebody" })

Warum werden die <div id="articlebody"> ... </div>Tags und Inhalte dazwischen NICHT zurückgegeben ? Es gibt nichts zurück. Und ich weiß, dass es existiert, weil ich direkt darauf starre

soup.prettify()

soup.find("div", { "id" : "articlebody" }) funktioniert auch nicht.

( BEARBEITEN: Ich habe festgestellt, dass BeautifulSoup meine Seite nicht richtig analysiert hat, was wahrscheinlich bedeutete, dass die Seite, die ich analysieren wollte, nicht richtig in SGML oder was auch immer formatiert ist.)

Tony Stark
quelle
(Für Ihre BEARBEITUNG hat diese Frage immer noch einen Wert als wiederverwendbare Ressource für andere, auch wenn der Parser auf Ihrer bestimmten Seite nicht funktioniert.)
smci

Antworten:

202

Sie sollten Ihr Beispieldokument veröffentlichen, da der Code einwandfrei funktioniert:

>>> import BeautifulSoup
>>> soup = BeautifulSoup.BeautifulSoup('<html><body><div id="articlebody"> ... </div></body></html')
>>> soup.find("div", {"id": "articlebody"})
<div id="articlebody"> ... </div>

Das Finden von <div>s in <div>s funktioniert auch:

>>> soup = BeautifulSoup.BeautifulSoup('<html><body><div><div id="articlebody"> ... </div></div></body></html')
>>> soup.find("div", {"id": "articlebody"})
<div id="articlebody"> ... </div>
Lukáš Lalinský
quelle
2
Mein Beispieldokument ist enorm. Ich spüre das Problem auf - ich denke, das funktioniert nicht bei Divs von Divs. Ich habe gezählt, wie viele Divs in dem Dokument mit print len ​​(Suppe ('div')) enthalten sind, was zu 10 führte, und ich kann KLAR mehr als 10 Divs mit Firebug sehen. Ich denke, es kann einfach keine Divs in Divs finden, also muss ich die Dinge Wrapper für Wrapper eingrenzen.
Tony Stark
8
Nun, dann ist es unmöglich, Ihre Frage zu beantworten. Kristallkugeln sind keine zuverlässige Methode zum Debuggen. :)
Lukáš Lalinský
1
Ich habe diesen Code ausprobiert. Das Div hat <embed> und ich kann die Einbettung darin nicht drucken.
Vincent
13
oder einfacherdiv = soup.find(id="articlebody")
jfs
4
odersoup.find('div', id='articlebody')
Trevor Boyd Smith
71

So finden Sie ein Element anhand seiner id:

div = soup.find(id="articlebody")
jfs
quelle
15

Beautiful Soup 4 unterstützt die meisten CSS-Selektoren mit dieser .select()Methode . Daher können Sie einen idSelektor verwenden, z.

soup.select('#articlebody')

Wenn Sie den Typ des Elements angeben müssen, können Sie vor dem Selektor einen Typselektor hinzufügen id:

soup.select('div#articlebody')

Die .select()Methode gibt eine Sammlung von Elementen zurück. Dies bedeutet, dass dieselben Ergebnisse wie im folgenden .find_all()Methodenbeispiel zurückgegeben werden :

soup.find_all('div', id="articlebody")
# or
soup.find_all(id="articlebody")

Wenn Sie nur ein einzelnes Element auswählen möchten, können Sie einfach die folgende .find()Methode verwenden :

soup.find('div', id="articlebody")
# or
soup.find(id="articlebody")
Josh Crozier
quelle
13

Ich denke, es gibt ein Problem, wenn die 'div'-Tags zu stark verschachtelt sind. Ich versuche, einige Kontakte aus einer Facebook-HTML-Datei zu analysieren, und die Beautifulsoup kann keine Tags "div" mit der Klasse "fcontent" finden.

Dies passiert auch bei anderen Klassen. Wenn ich im Allgemeinen nach Divs suche, werden nur diejenigen angezeigt, die nicht so stark verschachtelt sind.

Der HTML-Quellcode kann eine beliebige Seite von Facebook der Freundesliste eines Freundes von Ihnen sein (nicht der eines Ihrer Freunde). Wenn jemand es testen und Ratschläge geben kann, würde ich es wirklich schätzen.

Dies ist mein Code, in dem ich nur versuche, die Anzahl der Tags "div" mit der Klasse "fcontent" zu drucken:

from BeautifulSoup import BeautifulSoup 
f = open('/Users/myUserName/Desktop/contacts.html')
soup = BeautifulSoup(f) 
list = soup.findAll('div', attrs={'class':'fcontent'})
print len(list)
omar
quelle
9

Höchstwahrscheinlich hat der Standard-Beautifulsoup-Parser ein Problem. Ändern Sie einen anderen Parser wie 'lxml' und versuchen Sie es erneut.

liang
quelle
Das hat bei mir funktioniert, danke! Ich benutztesoup = BeautifulSoup(data, parser="html.parser")
Will-Hart
8

In der Beautifulsoup-Quelle ermöglicht diese Zeile, dass Divs in Divs verschachtelt werden. Ihre Besorgnis in Lukas 'Kommentar wäre also nicht gültig.

NESTABLE_BLOCK_TAGS = ['blockquote', 'div', 'fieldset', 'ins', 'del']

Ich denke, Sie müssen die gewünschten Attribute angeben, z

source.find('div', attrs={'id':'articlebody'})
dagoof
quelle
5

haben Sie versucht soup.findAll("div", {"id": "articlebody"})?

klingt verrückt, aber wenn Sie Sachen aus der Wildnis kratzen, können Sie mehrere Divs nicht ausschließen ...

user106514
quelle
4

Ich benutzte:

soup.findAll('tag', attrs={'attrname':"attrvalue"})

Als meine Syntax für find / findall; Dies sollte jedoch nicht anders sein, es sei denn, es gibt andere optionale Parameter zwischen dem Tag und der Attributliste.


quelle
4

Ist mir auch beim Versuch passiert, Google zu kratzen.
Am Ende habe ich Pyquery benutzt.
Installieren:

pip install pyquery

Verwenden:

from pyquery import PyQuery    
pq = PyQuery('<html><body><div id="articlebody"> ... </div></body></html')
tag = pq('div#articlebody')
Shoham
quelle
3

Hier ist ein Codefragment

soup = BeautifulSoup(:"index.html")
titleList = soup.findAll('title')
divList = soup.findAll('div', attrs={ "class" : "article story"})

Wie Sie sehen können, finde ich alle Tags und dann alle Tags mit class = "article"

Rekursion
quelle
0

Die IdImmobilie ist immer eindeutig gekennzeichnet. Das heißt, Sie können es direkt verwenden, ohne das Element anzugeben. Daher ist es ein Pluspunkt, wenn Ihre Elemente den Inhalt analysieren müssen.

divEle = soup.find(id = "articlebody")
Iqra.
quelle