Hallo liebe Boradmitglieder!
Ich lese aktuell mit BeautifulSoup4 und Requests HTML Seiten aus und hole mir hier dann Bilder und Dokumente.
Dies klappt auch soweit ganz gut! Manche der Hyperlinks haben aber einen falschen Aufbau. Diese sind mit "//subdomain.domanin.de" angegeben.
Diese werden aber nicht verarbeitet, da anscheinend "requests" nichts damit anfangen kann.
Jetzt würde ich gern die zwei "//" am Anfang entfernen, oder mit "https:" ergänzen.
Theoretisch könnte ich jetzt ja den String zerlegen und prüfen, ob die ersten zwei Zeichen davon // entsprechen, jedoch soll das Programm auch vielleicht mal erweitert werden und dann können hier noch komplett andere Zeichenfolgen stehen.
Gibt es eine einfache Möglichkeit, bestimmte Teilbereiche von Strings zu vergleichen, ohne den Umweg über die Zerlegung des Strings zu gehen?
Vielleicht hab ich nur die falschen Suchbegriffe, aber aktuell steh ich da vor einer Mauer.
Folgendes wäre erlaubt:
http://subdomain.domain.de
http://domain.de
https://subdomain.domain.de
https://domain.de
Verboten bzw. abzuändern:
//subdomain.domain.de
//domain.de
Ich hoffe ich bin nicht einfach zu faul und es muss wirklich so gemacht werden!? Wäre super, wenn jemand eine Idee hat.
Später würde ich gerne eine Indexierung bestimmter Domains machen. Also nur alle Links behalten und verfolgen, die auf die jeweilige Domain laufen. Alle externen Links sollen verworfen, oder in einer externen Liste gespeichert werden.
Vielen Dank schon mal an alle, die helfen können!
Vergleich von Hyperlinks bzw. abändern falscher Links
Hyperlinks gibt es in relativ und absolut.
Und relative Links mußt Du mit der Dokumenten-URL zu absoluten Pfade wandeln, bevor Du sie mit requests verwenden kannst.
Dazu benutzt man urllib.parse.join.
Und relative Links mußt Du mit der Dokumenten-URL zu absoluten Pfade wandeln, bevor Du sie mit requests verwenden kannst.
Dazu benutzt man urllib.parse.join.
Code: Alles auswählen
urllib.parse.urljoin('https://abc.de/ein/pfad/a.html', '//bilder.abc.de/b.gif')
# 'https://bilder.abc.de/b.gif'
Danke schon mal für die Hilfe!
urllib.parse.join schau ich mir auf jeden Fall mal an.
Aktuell habe ich mir mit try/except beholfen. Die URL die mit // anfängt und nicht aufgelöst werden konnte, soll sowieso erst einmal ignoriert werden.
Ist jetzt sicherlich nicht sauber umgesetzt, aber es funktioniert schon mal
.
Wünsche euch noch einen schönen Sonntag!
urllib.parse.join schau ich mir auf jeden Fall mal an.
Aktuell habe ich mir mit try/except beholfen. Die URL die mit // anfängt und nicht aufgelöst werden konnte, soll sowieso erst einmal ignoriert werden.
Ist jetzt sicherlich nicht sauber umgesetzt, aber es funktioniert schon mal

Wünsche euch noch einen schönen Sonntag!
Man könnte das auch mit urlparse() lösen:
Code: Alles auswählen
from urllib.parse import urlparse
def get_url(link, domain="", default_protocol="https"):
replacements = {}
parsed = urlparse(link)
if not parsed.scheme:
replacements["scheme"] = default_protocol
if not parsed.netloc:
replacements["netloc"] = domain
return parsed._replace(**replacements).geturl()
def main():
print(get_url("//subdomain.domain.de"))
base = "www.test.de"
for link in ("aktuelles.php", "fotos.php", "about.html"):
print(get_url(link, base))
if __name__ == "__main__":
main()
Hier mit dem "Same Origin"-Ansatz:
Code: Alles auswählen
from urllib.parse import urlparse
def get_url(link, origin="", default_protocol="https"):
replacements = {}
parsed = urlparse(link)
if origin and parsed.netloc not in ("", origin):
raise ValueError(f"External URL: {link}")
if not parsed.scheme:
replacements["scheme"] = default_protocol
if not parsed.netloc:
replacements["netloc"] = origin
return parsed._replace(**replacements).geturl()
def main():
print(get_url("//subdomain.domain.de"))
origin = "www.test.de"
for link in ("aktuelles.php", "fotos.php", "about.html"):
print(get_url(link, origin))
print(get_url("https://www.spam.com/img56744.jpg", origin))
if __name__ == "__main__":
main()

Weil hier mehr gefordert ist als das stumpfe Zusammensetzen von URL-Fragmenten. Man muss sich ja erstmal die Bestandteile näher anschauen und dann ggf Ersetzungen vornehmen. Letzteres wäre auch mit urljoin() möglich, aber dann würde jemand anders wahrscheinlich fragen, warum extra urljoin() bemüht wird, wenn man schon den geparsten Zwischenstand hat...
Warum sollte man eine Funktion benutzen, die gut getestet ist und alle Fälle abdeckt?
Code: Alles auswählen
from urllib.parse import urlparse, urljoin
def get_links():
""" hier ein paar Beispiellinks """
return [
"http://test.de/static/bilder/hund.jpg",
"//example.com/external/url.html",
"/same_url/index.html",
"../relative/index.html",
]
def main():
document_url = "https://test.de/pfad/zu/document.html"
origin = urlparse(document_url).netloc
for link in get_links():
absolute_link = urljoin(document_url, link)
is_external = urlparse(absolute_link).netloc != origin
print(absolute_link, "external" if is_external else "internal")
if __name__ == "__main__":
main()