Seite 1 von 1

Beautiful Soup findall Frage (gelöst)

Verfasst: Mittwoch 9. September 2009, 13:54
von schneseb
Hallo zusammen,

ich befasse mich erst seit kurzem mit Python und bin doch recht angetan von den einfachen Möglichkeiten, mit denen ich viel erreichen kann.

Konkret habe ich eine Frage zu der Methode findall von Beautiful Soup. Ich habe in der Dokumentation (http://www.crummy.com/software/Beautifu ... *kwargs%29) schon eine wirklich mächtige Möglichkeit gefunden, bestimmte Tags zu extrahieren. Vielleicht ist mein Wunsch jetzt gar nicht so weit und jemand weiß das.

Bis jetzt habe ich sowas anhand der Doku erstellt.

Code: Alles auswählen

allTds = soup.findAll('td',{'class' : 'std'})
Damit finde ich alle TD tags, die als class "std" haben. Ich zeige jetzt mal die Zeile, die ich genau möchte:

Code: Alles auswählen

<td class="std" onclick="test("test");">
Hier steht der text, der mich interessiert.</td>
Ich würde also gerne in den Aufruf oben noch gerne einbauen, dass ich das nur haben will, wenn noch die onklick Methode mit in dem td Tag enthalten ist.

Geht das auch so einfach irgendwie, wie das Beispiel oben, oder muss man dann mit RegExp etc. arbeiten?

Danke!

Verfasst: Mittwoch 9. September 2009, 14:06
von snafu
Ich würde vermuten:

Code: Alles auswählen

soup.findAll(
    'td',
   {'class'   : 'std',
    'onclick' :  True}
)
(Zeileneinrückungen zwecks Lesbarkeit, ist Geschmackssache)

Verfasst: Mittwoch 9. September 2009, 14:10
von schneseb
Hallo,

wie geil ist das denn? :D Funktioniert bestens! Irgendwie mag ich Python 8)

Besten dank für deine Hilfe!

Verfasst: Mittwoch 9. September 2009, 14:18
von snafu
War jetzt eigentlich nur den von dir verlinkten Abschnitt lesen und ein bißchen kombinieren. ;)

Verfasst: Mittwoch 9. September 2009, 17:47
von BlackJack
Was die Einrückung von dem `dict` angeht -- sollte nicht auch das hier gehen!?

Code: Alles auswählen

soup.findAll('td', 'std', onclick=True)

Verfasst: Mittwoch 9. September 2009, 19:22
von snafu
BlackJack hat geschrieben:

Code: Alles auswählen

soup.findAll('td', 'std', onclick=True)
Meines Wissens müsste man hier ``class='std'`` als zweites Argument einsetzen und dann zickt Python rum wegen dem reservierten Schlüsselwort. Deshalb wurde die Alternative geschaffen, die Attribute als `dict` zu übergeben.

Verfasst: Mittwoch 9. September 2009, 20:16
von BlackJack
@snafu: Nein deshalb kann man das ``class``-Attribut auch ohne Keyword als zweites Argument übergeben, weil es eben so häufig als HTML-Attribut vorkommt und man so nicht zwingend ein `dict` erstellen muss. Und das `findAll` kann man sich auch noch sparen:

Code: Alles auswählen

In [12]: soup
Out[12]: <body><p class="c">A</p><p>B</p></body>

In [13]: soup.findAll('p')
Out[13]: [<p class="c">A</p>, <p>B</p>]

In [14]: soup.findAll('p', 'c')
Out[14]: [<p class="c">A</p>]

In [15]: soup('p', 'c')
Out[15]: [<p class="c">A</p>]

Verfasst: Mittwoch 9. September 2009, 22:29
von jbs
Warum hat man denn den Weg so gewählt und ``class`` als Parameter festgelegt?

Verfasst: Mittwoch 9. September 2009, 22:36
von BlackJack
@jbs: Ich dachte das wird aus snafu's und meinem letzten Beitrag deutlich: Das HTML-Attribut "class" wird häufig benötigt um Elemente auszuwählen, man kann es aber nicht als Schlüsselwort-Argument schreiben, weil es ein reserviertes Wort der Sprache Python ist. Man müsste also sonst den umständlicheren Weg über ein Dictionary gehen.

Verfasst: Mittwoch 9. September 2009, 22:53
von jbs
Das war mir klar. Nur warum verwendet man ein Schlüsselwort?

Verfasst: Mittwoch 9. September 2009, 23:10
von snafu
jbs hat geschrieben:Nur warum verwendet man ein Schlüsselwort?
Wie schon gesagt: Man verwendet *kein* Schlüsselwort für `class`.

Verfasst: Donnerstag 10. September 2009, 08:14
von schneseb
snafu hat geschrieben:War jetzt eigentlich nur den von dir verlinkten Abschnitt lesen und ein bißchen kombinieren. ;)
:oops: Du hast Recht, nachdem du das geschrieben hat und ich noch weiter rumgestöbert habe, hab ich es auch gelesen :)