Schöne Suppe - Suche den Baum

Es gibt viele Beautifulsoup-Methoden, mit denen wir einen Analysebaum durchsuchen können. Die beiden am häufigsten verwendeten Methoden sind find () und find_all ().

Bevor wir über find () und find_all () sprechen, sehen wir uns einige Beispiele für verschiedene Filter an, die Sie an diese Methoden übergeben können.

Arten von Filtern

Wir haben verschiedene Filter, die wir an diese Methoden übergeben können, und das Verständnis dieser Filter ist von entscheidender Bedeutung, da diese Filter in der gesamten Such-API immer wieder verwendet werden. Wir können diese Filter basierend auf dem Namen des Tags, seinen Attributen, dem Text einer Zeichenfolge oder gemischt aus diesen verwenden.

Ein Faden

Eine der einfachsten Filterarten ist eine Zeichenfolge. Wenn Sie eine Zeichenfolge an die Suchmethode und an Beautifulsoup übergeben, wird eine Übereinstimmung mit dieser genauen Zeichenfolge durchgeführt.

Der folgende Code enthält alle <p> -Tags im Dokument -

>>> markup = BeautifulSoup('<p>Top Three</p><p><pre>Programming Languages are:</pre></p><p><b>Java, Python, Cplusplus</b></p>')
>>> markup.find_all('p')
[<p>Top Three</p>, <p></p>, <p><b>Java, Python, Cplusplus</b></p>]

Regulären Ausdruck

Sie können alle Tags finden, die mit einer bestimmten Zeichenfolge / einem bestimmten Tag beginnen. Vorher müssen wir das re-Modul importieren, um reguläre Ausdrücke zu verwenden.

>>> import re
>>> markup = BeautifulSoup('<p>Top Three</p><p><pre>Programming Languages are:</pre></p><p><b>Java, Python, Cplusplus</b></p>')
>>>
>>> markup.find_all(re.compile('^p'))
[<p>Top Three</p>, <p></p>, <pre>Programming Languages are:</pre>, <p><b>Java, Python, Cplusplus</b></p>]

Aufführen

Sie können mehrere Tags zum Suchen übergeben, indem Sie eine Liste bereitstellen. Der folgende Code findet alle <b> - und <pre> -Tags -

>>> markup.find_all(['pre', 'b'])
[<pre>Programming Languages are:</pre>, <b>Java, Python, Cplusplus</b>]

Wahr

True gibt alle Tags zurück, die es finden kann, aber keine eigenen Zeichenfolgen -

>>> markup.find_all(True)
[<html><body><p>Top Three</p><p></p><pre>Programming Languages are:</pre>
<p><b>Java, Python, Cplusplus</b> </p> </body></html>, 
<body><p>Top Three</p><p></p><pre> Programming Languages are:</pre><p><b>Java, Python, Cplusplus</b></p>
</body>, 
<p>Top Three</p>, <p></p>, <pre>Programming Languages are:</pre>, <p><b>Java, Python, Cplusplus</b></p>, <b>Java, Python, Cplusplus</b>]

Um nur die Tags aus der obigen Suppe zurückzugeben -

>>> for tag in markup.find_all(True):
(tag.name)
'html'
'body'
'p'
'p'
'pre'
'p'
'b'

finde alle()

Mit find_all können Sie alle Vorkommen eines bestimmten Tags aus der Seitenantwort als - extrahieren

Syntax

find_all(name, attrs, recursive, string, limit, **kwargs)

Lassen Sie uns einige interessante Daten aus IMDB- „Bestbewerteten Filmen“ aller Zeiten extrahieren.

>>> url="https://www.imdb.com/chart/top/?ref_=nv_mv_250"
>>> content = requests.get(url)
>>> soup = BeautifulSoup(content.text, 'html.parser')
#Extract title Page
>>> print(soup.find('title'))
<title>IMDb Top 250 - IMDb</title>

#Extracting main heading
>>> for heading in soup.find_all('h1'):
   print(heading.text)
Top Rated Movies

#Extracting sub-heading
>>> for heading in soup.find_all('h3'):
   print(heading.text)
   
IMDb Charts
You Have Seen
   IMDb Charts
   Top India Charts
Top Rated Movies by Genre
Recently Viewed

Von oben sehen wir, dass find_all uns alle Elemente gibt, die den von uns definierten Suchkriterien entsprechen. Alle Filter, die wir mit find_all () verwenden können, können auch mit find () und anderen Suchmethoden wie find_parents () oder find_s Geschwistern () verwendet werden.

finden()

Wir haben oben gesehen, dass find_all () verwendet wird, um das gesamte Dokument zu scannen, um den gesamten Inhalt zu finden, aber etwas, die Anforderung besteht darin, nur ein Ergebnis zu finden. Wenn Sie wissen, dass das Dokument nur ein <body> -Tag enthält, ist es Zeitverschwendung, das gesamte Dokument zu durchsuchen. Eine Möglichkeit besteht darin, find_all () mit limit = 1 jedes Mal aufzurufen, oder wir können die find () -Methode verwenden, um dasselbe zu tun -

Syntax

find(name, attrs, recursive, string, **kwargs)

Im Folgenden geben zwei verschiedene Methoden die gleiche Ausgabe -

>>> soup.find_all('title',limit=1)
[<title>IMDb Top 250 - IMDb</title>]
>>>
>>> soup.find('title')
<title>IMDb Top 250 - IMDb</title>

In den obigen Ausgaben sehen wir, dass die Methode find_all () eine Liste mit einem einzelnen Element zurückgibt, während die Methode find () ein einzelnes Ergebnis zurückgibt.

Ein weiterer Unterschied zwischen der Methode find () und find_all () ist -

>>> soup.find_all('h2')
[]
>>>
>>> soup.find('h2')

Wenn die Methodeoup.find_all () nichts finden kann, gibt sie eine leere Liste zurück, während find () None zurückgibt.

find_parents () und find_parent ()

Im Gegensatz zu den Methoden find_all () und find (), die den Baum durchlaufen und die Nachkommen des Tags betrachten, machen die Methoden find_parents () und find_parents () das Gegenteil, sie durchlaufen den Baum nach oben und betrachten die Eltern eines Tags (oder eines Strings).

Syntax

find_parents(name, attrs, string, limit, **kwargs)
find_parent(name, attrs, string, **kwargs)

>>> a_string = soup.find(string="The Godfather")
>>> a_string
'The Godfather'
>>> a_string.find_parents('a')
[<a href="/title/tt0068646/" title="Francis Ford Coppola (dir.), Marlon Brando, Al Pacino">The Godfather</a>]
>>> a_string.find_parent('a')
<a href="/title/tt0068646/" title="Francis Ford Coppola (dir.), Marlon Brando, Al Pacino">The Godfather</a>
>>> a_string.find_parent('tr')
<tr>

<td class="posterColumn">
<span data-value="2" name="rk"></span>
<span data-value="9.149038526210072" name="ir"></span>
<span data-value="6.93792E10" name="us"></span>
<span data-value="1485540" name="nv"></span>
<span data-value="-1.850961473789928" name="ur"></span>
<a href="/title/tt0068646/"> <img alt="The Godfather" height="67" src="https://m.media-amazon.com/images/M/MV5BM2MyNjYxNmUtYTAwNi00MTYxLWJmNWYtYzZlODY3ZTk3OTFlXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UY67_CR1,0,45,67_AL_.jpg" width="45"/>
</a> </td>
<td class="titleColumn">
2.
<a href="/title/tt0068646/" title="Francis Ford Coppola (dir.), Marlon Brando, Al Pacino">The Godfather</a>
<span class="secondaryInfo">(1972)</span>
</td>
<td class="ratingColumn imdbRating">
<strong title="9.1 based on 1,485,540 user ratings">9.1</strong>
</td>
<td class="ratingColumn">
<div class="seen-widget seen-widget-tt0068646 pending" data-titleid="tt0068646">
<div class="boundary">
<div class="popover">
<span class="delete"> </span><ol><li>1<li>2<li>3<li>4<li>5<li>6<li>7<li>8<li>9<li>10</li>0</li></li></li></li&td;</li></li></li></li></li></ol> </div>
</div>
<div class="inline">
<div class="pending"></div>
<div class="unseeable">NOT YET RELEASED</div>
<div class="unseen"> </div>
<div class="rating"></div>
<div class="seen">Seen</div>
</div>
</div>
</td>
<td class="watchlistColumn">

<div class="wlb_ribbon" data-recordmetrics="true" data-tconst="tt0068646"></div>
</td>
</tr>
>>>
>>> a_string.find_parents('td')
[<td class="titleColumn">
2.
<a href="/title/tt0068646/" title="Francis Ford Coppola (dir.), Marlon Brando, Al Pacino">The Godfather</a>
<span class="secondaryInfo">(1972)</span>
</td>]

Es gibt acht ähnliche Methoden -

find_next_siblings(name, attrs, string, limit, **kwargs)
find_next_sibling(name, attrs, string, **kwargs)

find_previous_siblings(name, attrs, string, limit, **kwargs)
find_previous_sibling(name, attrs, string, **kwargs)

find_all_next(name, attrs, string, limit, **kwargs)
find_next(name, attrs, string, **kwargs)

find_all_previous(name, attrs, string, limit, **kwargs)
find_previous(name, attrs, string, **kwargs)

Wo,

find_next_siblings() und find_next_sibling() Methoden iterieren über alle Geschwister des Elements, die nach dem aktuellen kommen.

find_previous_siblings() und find_previous_sibling() Methoden durchlaufen alle Geschwister, die vor dem aktuellen Element stehen.

find_all_next() und find_next() Methoden durchlaufen alle Tags und Zeichenfolgen, die nach dem aktuellen Element stehen.

find_all_previous und find_previous() Methoden durchlaufen alle Tags und Zeichenfolgen, die vor dem aktuellen Element stehen.

CSS-Selektoren

Die BeautifulSoup-Bibliothek zur Unterstützung der am häufigsten verwendeten CSS-Selektoren. Mit Hilfe der Methode select () können Sie mithilfe von CSS-Selektoren nach Elementen suchen.

Hier einige Beispiele -

>>> soup.select('title')
[<title>IMDb Top 250 - IMDb</title>, <title>IMDb Top Rated Movies</title>]
>>>
>>> soup.select("p:nth-of-type(1)")
[<p>The Top Rated Movie list only includes theatrical features.</p>, <p> class="imdb-footer__copyright _2-iNNCFskmr4l2OFN2DRsf">© 1990-2019 by IMDb.com, Inc.</p>]
>>> len(soup.select("p:nth-of-type(1)"))
2
>>> len(soup.select("a"))
609
>>> len(soup.select("p"))
2

>>> soup.select("html head title")
[<title>IMDb Top 250 - IMDb</title>, <title>IMDb Top Rated Movies</title>]
>>> soup.select("head > title")
[<title>IMDb Top 250 - IMDb</title>]

#print HTML code of the tenth li elemnet
>>> soup.select("li:nth-of-type(10)")
[<li class="subnav_item_main">
<a href="/search/title?genres=film_noir&sort=user_rating,desc&title_type=feature&num_votes=25000,">Film-Noir
</a> </li>]