Download von Webseiten

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
DanielAC
User
Beiträge: 5
Registriert: Dienstag 10. November 2020, 15:57

Hallo zusammen,

wenn ich Webseiten herunterladen möchte, sehe ich in der gespeicherten Datei manchmal nicht alle Links, die auf der eigentlichen Seite vorhanden sind.

Beispiel ist https://www.adac.de/rund-ums-fahrzeug/a ... 124-spider

Mein Code sieht so aus:

Code: Alles auswählen

    url = "https://www.adac.de/rund-ums-fahrzeug/autokatalog/marken-modelle/abarth/124-spider"

    response = urllib.request.urlopen(url)
    webContent = response.read()
    
    filename = Dateiname

    f = open(filename, 'wb')
    f.write(webContent)
    f.close
Mache ich hier etwas falsch oder kann ich das irgendwie beheben?

Vielen Dank und VG
Daniel
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@DanielAC: Die Webseite enthält JavaScript das weitere Daten dynamisch nachlädt. Das müsstest Du auch nachprogrammieren.

Zum Quelltext: `Dateiname` ist nicht definiert.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).

Dateien die man öffnet, sollte man auch wieder schliessen, also `close()` auch *aufrufen*. Oder besser: die ``with``-Anweisung verwenden. Was man auch bei der Verbindung zum Webserver machen sollte.

`f` ist kein guter Name, wie einbuchstabige Abkürzungen selten gute Namen sind.

`pathlib.Path`-Objekte haben eine Methode zum schreiben von Daten in einer Datei.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import urllib.request
from pathlib import Path


def main():
    url = (
        "https://www.adac.de/rund-ums-fahrzeug/autokatalog/marken-modelle"
        "/abarth/124-spider"
    )
    with urllib.request.urlopen(url) as response:
        web_content = response.read()
    
    filename = "test.html"
    Path(filename).write_bytes(web_content)


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
DanielAC
User
Beiträge: 5
Registriert: Dienstag 10. November 2020, 15:57

Und wie löse ich das Problem mit JS? Ich kenne mich damit leider gar nicht aus und bin in Python auch nicht gerade ein Experte...
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mit JS garnicht. Du kannst entweder im Browser schauen, was für requests an die Server die Daten liefern, und die selbst absetzen. Oder mit Selenium einen Browser fernsteuern und so die Daten abgreifen.
DanielAC
User
Beiträge: 5
Registriert: Dienstag 10. November 2020, 15:57

Das ist leider alles ein wenig ernüchternd.
Die Steuerung mit Selenium ist zwar ganz praktisch, aber letztendlich ein wenig zu langsam, wenn ich das nicht nur für einige Seiten machen möchte...

Wie kann ich denn erkennen, welche Inhalte dynamisch nachgeladen werden?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Durch individuelle Betrachtung. Automatisch wird es schwer. Da könntest du direkte Anfragen mit selenium getriebenen Vergleichen.
DanielAC
User
Beiträge: 5
Registriert: Dienstag 10. November 2020, 15:57

Eine interessante Möglichkeit ist offenbar Pywebcopy mit der Funktion save_website.
Das klappt prinzipiell. Er lädt tatsächlich die benötigten Informationen herunter. Leider scheint die Funktion aber irgendwo zu hängen, denn nach dem Download (zumindest nach dem Download von den von mir benötigten Daten) endet das Programm nicht, sondern wird noch weiter ausgeführt und macht nichts spannendes mehr.

Kann ich eine Funktion nach z.B. 10 Sekunden Laufzeit irgendwie abschießen um dann in einer Schleife den Download mit einer neuen Seite anzustoßen?
Da Python den Code ja zeilenweise verarbeitet müsste ja irgendwie eine Parallelisierung eingebaut werden.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nein, aber man kann natürlich subprocess benutzen, und einen Prozess abschiessen.
Antworten