getpage - ein wget für eine einzelne Seite in eine Datei

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
Remline
User
Beiträge: 5
Registriert: Mittwoch 30. November 2011, 13:18

Hi,

ich bastle gerade an einem schönen kleinen Tool, das mittlerweile auch schon seine Aufgabe erfüllen kann. Es findet sich hier

https://github.com/andydrop/getpage

Das Script holt sich, wie der Name schon vermuten lässt eine Seite aus dem Internet, und speichert sie so originalgetreu wie möglich also inklusive Bildern, Scripten und Stylesheets in einer einzelnen Datei im MIME-HTML Format.
Diese Datei kann man sich dann später auch offline in seinem Browser anschauen. Später habe ich dann auch noch mehr damit vor.
Soweit funktioniert es schon.

Derzeit ist das ganze noch sehr roh, es enthält zum Beispiel nur ein Minimum an Fehlerbehandlungen, es muß noch robuster werden, besser in GUI und Funktionsteil aufgeteilt werden, Ich selbst bin in Python auf dem Level, das ich mein Zeugs runterprogrammiert bekomme, aber die Standard-Lib noch viel zu wenig kenne. Daher lerne ich im Verlauf dieses Projekts auch immer wieder interessante Dinge kennen. Etwas, was ich auch gerne intensiver kennenlernen möchte ist Zusammenarbeit in so einem Projekt mit anderen, daher würde ich mir 1-2 Mitstreiter wünschen, die auch gerne noch weniger von Python kennen als ich.

Über Feedback zum Projekt freue ich mich natürlich auch immer.

Andy
BlackJack

@Remline: `GetPage` wäre eher ein Name für eine Funktion oder Methode die jeweils Tätigkeiten entsprechen, während Klassen eher für „Dinge” stehen.

Bei Python 2.x sollten Klassen explizit von `object` erben, damit man „new style”-Klassen bekommt bei denen alles funktioniert was Python so bietet. Zum Beispiel `property()`\s.

Die Klassenattribute sind zumindest für die veränderbaren Objekte falsch.

In der `__init__()`-Methode wird das `options`-Argument ignoriert.

`_base_url` wird erst in `add_html()` als Attribut eingeführt. Man sollte vermeiden ausserhalb der Initialisierung neue Attribute hinzu zu fügen. Ausserdem sehe ich da ein Problem mit dem rekursiven Aufruf der Methode wenn man <iframe>-Inhalte hinzufügt, denn da wird das Argument ja überschrieben nach dem rekursiven Aufstieg ist es dann möglicherweise an falsche Werte gebunden.

Der Quelltext auf Modulebene sollte in einer eigenen Funktion verschwinden. Die Namen die dort gebunden werden stehen sonst modulweit zur Verfügung und es besteht die Gefahr, dass man absichtlich oder unabsichtlich Werte benutzt, auf die man keinen Zugriff haben sollte.

Das `_urls`-Attribut sollte wohl eher ein `set()` sein. Ein Dictionary bei dem Schlüssel und Wert immer identisch sind, ist nicht so sinnvoll. Beim Hinzufügen sehe ich auch ein Muster was man wahrscheinlich aus dem Quelltext heraus ziehen kann.

`logging` steht zwar in den Importen, wird aber nicht verwendet. Stattdessen findet man entsprechende ``print``-Anweisungen. Die module `sys` und `smtplib` werden auch importiert aber nicht verwendet.

Ich musste selbst schon mal mit Quelltext arbeiten wo jemand einfach die Kommentare zur Beschreibung von Funktionen von irgendeiner Funktion auf andere kopiert hat, nur damit alles ”dokumentiert” ist. Mit so etwas kannst Du Leute die Deinen Code später mal warten müssen echt wütend machen und frustrieren…

Beim CSS würde ich einen Parser verwenden und nicht mit regulären Ausdrücken selbst etwas basteln.

In `_add_image()` gibt es das erste mal eine Ausnahmebehandlung für HTTP. Warum nur dort? Allerdings besteht die Behandlung lediglich aus einer Ausgabe und dem Ignorieren der Ausnahme. Das Herunterladen von irgend etwas kommt auch in mehreren Methoden vor und führt dort immer zu gleichen oder zumindest ähnlichen Zeilen.

`_add_iframe()` scheint einfach mittendrin auf zu hören‽

`_get_base_url()` wird nirgends benutzt und wäre auch keine echte Methode. Und ``pass`` als start einer Funktion? `o` als Name?

Ich sehe bei `_snapshot_save()` weder einen Schnappschuss noch das irgend etwas gespeichert wird‽ Der Quelltext ist komisch und nicht robust. Die beiden Ersetzungen sind nicht sicher weil sie URLs für Bilder zerstören können und die letzten beiden Zeilen sind WTF?-Material.

`_snapshot_save()` und `_remove_comments()` sind keine Methoden.

In `retrieve()` sind zwei Fehler: Die Datei muss im Binärformat geöffnet werden, sonst stimmen zumindest unter Windows am Ende die Zeilenenden nicht. Und man sollte die Datei auch wieder schliessen. Es reicht nicht die Methode zu referenzieren — man muss sie auch aufrufen. Oder man verwendet gleich die ``with``-Anweisung. Am besten auch einen besseren Namen als `f`.

Insgesamt stellt sich die Frage nach dem Sinn oder zumindest der Ausgestaltung der Klasse. So wie sie jetzt entworfen ist, erstellt man ein Exemplar — und man kann nur eines gleichzeitig verwenden — ruft einmal `retrieve()` darauf auf, und muss das Exemplar dann wegwerfen. Das würde ich mindestens in eine Funktion kapseln und die Klasse als nicht-öffentlichen Teil der API definieren.

Der Quelltext hält sich was Zeilenlänge und Leerzeichen und -zeilen angeht nicht an PEP 8 -- Style Guide for Python Code.
Antworten