Link mit bs4 lesen - aber nicht alle!

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
torsten_156
User
Beiträge: 43
Registriert: Freitag 5. April 2019, 20:10

Hallo,
ich möchte gern mit bs4 links der Website "https://www.bergfex.at/oesterreich/" auslesen. Mit folgendem Code kann ich nun ALLE Links dieser Seite lesen:

Code: Alles auswählen

for item in html.find_all('a'):
    print(item.get('href'))
Soweit so gut. Mich interessieren aber nur bestimmte Links! Ich benötige lediglich die Links aus folgendem Bereich der Seite:

Code: Alles auswählen

<div class="txt_markup grid cols2">
	<div class="col">
		<ul>
			<li style="font-weight: bold;">
			<a href="/achensee/">Achensee</a>
			</li>
			<li style="font-weight: bold;">
			<a href="/alpbachtal/">Alpbach - Ski Juwel Alpbachtal Wildschönau</a>
			</li>
			<li>
			<a href="/astenberg-wiesing/">Astenberg / Wiesing - Achensee</a>
			</li>
Wie muss ich hier nun vorgehen, damit ich nur den Bereich <div class="col"> lese?

VG
Torsten
ElektroBerry
User
Beiträge: 31
Registriert: Samstag 16. Mai 2020, 18:52

Erstmal das "div"-Element mit der passenden Klasse finden:
Das "div"-Element class="col" kommt zu häufig im Quelltext vor. Deswegen wähle ich das höhere "div"-Element aus.

Code: Alles auswählen

html.find("div", class_="txt_markup grid cols2")
Dann so wie du es schon kennst jedes "li"-Element finden:

Code: Alles auswählen

html.find("div", class_="txt_markup grid cols2").find_all("li")

Code: Alles auswählen

import urllib.parse  # Um die Url zusammenzufügen
for listenelement in html.find("div", class_="txt_markup grid cols2").find_all("li"):
    print(f"Ort: {listenelement.a.text}")
    print(listenelement.a["href"])
    url = urllib.parse.urljoin(url, listenelement.a["href"])
    print(f"{url}\n")
Ja gut. Aber wenn ich mir die Webseite genauer ansehe, möchte man vielleicht doch alle "col" klassen durchsuchen:

Code: Alles auswählen

for element in html.find_all("div", class_="col"):
    for item in element.find_all("li"):
        print(item.a["href"])
torsten_156
User
Beiträge: 43
Registriert: Freitag 5. April 2019, 20:10

Habe es versucht und erhalte diesen Fehler:

Code: Alles auswählen

AttributeError: 'NoneType' object has no attribute 'find_all'
Ich habe auch schon versucht die class_ auf die direkt übergeordnete Klasse "col" der jeweiligen Links zu setzen. Aber da findet er nichts und springt direkt aus for heraus.
torsten_156
User
Beiträge: 43
Registriert: Freitag 5. April 2019, 20:10

Mich interessieren nur die Links zu den jeweiligen Skigebieten. So wie ich das sehe sind diese so strukturiert:
Main -> Detail -> section left -> txt_markup grid cols2

Das txt_markup grid cols2 gibt es dann mehrfach. In diesem ist dann immer die class "col" zu finden, die die jeweiligen Links beinhaltet.
ElektroBerry
User
Beiträge: 31
Registriert: Samstag 16. Mai 2020, 18:52

Dann wurde das Element nicht gefunden. Es wurde None zurück gegeben und dann wurde versucht ".find_all" darauf anzuwenden.

Ich habe noch ein wenig probiert und dies gibt mir alle gesuchten Links aus:

Code: Alles auswählen

for element in html.find_all("div", class_="txt_markup grid cols2"):
    for item in element.find_all("li"):
        print(item.a["href"])
Um jetzt alle None-Elemente abzufangen, würde ich dies hier einmal probieren:

Code: Alles auswählen

for element in html.find_all("div", class_="txt_markup grid cols2"):
    if element:
        for item in element.find_all("li"):
            if item.a:
                print(item.a["href"])
torsten_156
User
Beiträge: 43
Registriert: Freitag 5. April 2019, 20:10

SUPER! Genau so funktioniert es :-)

VIELEN Dank für die Unterstützung
Grüße Torsten
Antworten