Seite 1 von 1
Vergleich von Hyperlinks bzw. abändern falscher Links
Verfasst: Freitag 16. April 2021, 17:37
von Snakepit
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!
Re: Vergleich von Hyperlinks bzw. abändern falscher Links
Verfasst: Samstag 17. April 2021, 09:30
von sparrow
Ein URL für eine Web-Ressource beginnend mit // ist nicht "falsch" sondern laut Spezifikationen gültig.
Webbrowser setzen als Protokoll, soweit ich weiß, das Protokoll, mit dem die Seite aufgerufen wurde.
Re: Vergleich von Hyperlinks bzw. abändern falscher Links
Verfasst: Samstag 17. April 2021, 12:14
von Sirius3
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.
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'
Re: Vergleich von Hyperlinks bzw. abändern falscher Links
Verfasst: Sonntag 18. April 2021, 09:09
von Snakepit
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!
Re: Vergleich von Hyperlinks bzw. abändern falscher Links
Verfasst: Sonntag 18. April 2021, 10:36
von snafu
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()
Re: Vergleich von Hyperlinks bzw. abändern falscher Links
Verfasst: Sonntag 18. April 2021, 11:02
von Sirius3
@snafu: warum sollte man das so kompliziert machen, wenn es mit urljoin schon eine fertige Funktion gibt, die auch alle anderen Fälle von relativen URLs abdeckt?
Re: Vergleich von Hyperlinks bzw. abändern falscher Links
Verfasst: Sonntag 18. April 2021, 11:23
von snafu
Snakepit hat geschrieben: ↑Freitag 16. April 2021, 17:37
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.
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()
Anstelle des ValueErrors würde man im tatsächlichen Programm wahrscheinlich eine eigene Exception verwenden und bei deren Auftreten entsprechend den externen Link verwerfen bzw gesondert speichern. Das wirst du aber sicher auch alleine hinkriegen.

Re: Vergleich von Hyperlinks bzw. abändern falscher Links
Verfasst: Sonntag 18. April 2021, 11:46
von snafu
Sirius3 hat geschrieben: ↑Sonntag 18. April 2021, 11:02
@snafu: warum sollte man das so kompliziert machen, wenn es mit urljoin schon eine fertige Funktion gibt, die auch alle anderen Fälle von relativen URLs abdeckt?
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...
Re: Vergleich von Hyperlinks bzw. abändern falscher Links
Verfasst: Sonntag 18. April 2021, 11:55
von Sirius3
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()
Re: Vergleich von Hyperlinks bzw. abändern falscher Links
Verfasst: Sonntag 18. April 2021, 20:11
von snafu
Okay, du hast mich überzeugt: urljoin() tut, was es soll.
