Seite 1 von 1

Link mit bs4 lesen - aber nicht alle!

Verfasst: Mittwoch 30. Dezember 2020, 18:51
von torsten_156
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

Re: Link mit bs4 lesen - aber nicht alle!

Verfasst: Mittwoch 30. Dezember 2020, 19:24
von ElektroBerry
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"])

Re: Link mit bs4 lesen - aber nicht alle!

Verfasst: Mittwoch 30. Dezember 2020, 19:52
von torsten_156
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.

Re: Link mit bs4 lesen - aber nicht alle!

Verfasst: Mittwoch 30. Dezember 2020, 20:03
von torsten_156
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.

Re: Link mit bs4 lesen - aber nicht alle!

Verfasst: Mittwoch 30. Dezember 2020, 20:07
von ElektroBerry
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"])

Re: Link mit bs4 lesen - aber nicht alle!

Verfasst: Mittwoch 30. Dezember 2020, 20:49
von torsten_156
SUPER! Genau so funktioniert es :-)

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