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.)


(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>

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


4
odersoup.find('div', id='articlebody')
Trevor Boyd Smith

71

So finden Sie ein Element anhand seiner id:

div = soup.find(id="articlebody")

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")

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)

9

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


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'})

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 ...


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.


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')

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"


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")
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.