Seite 1 von 1

Datei aus dem Internet herunterladen (download_file.py)

Verfasst: Montag 25. April 2005, 20:57
von gerold
(Stichworte: http, https, Benutzername, Passwort)

Hi!

Mit diesem kleinen Codeausschnitt kann man eine Datei aus dem Internet herunterladen. Und das funktioniert auch, wenn man dafür einen Benutzernamen und ein Passwort angeben muss.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset: 3 -*-

import urllib2 as __urllib2
import base64 as __base64


#--------------------------------------------------------------
def download_file(url, webuser = None, webpass = None):
   """
   Datei aus dem Internet herunterladen
   """

   request =  __urllib2.Request(url)

   if webuser:
      base64string = __base64.encodestring('%s:%s' % (webuser, webpass))[:-1]
      request.add_header("Authorization", "Basic %s" % base64string)

   htmlFile = __urllib2.urlopen(request)
   htmlData = htmlFile.read()
   htmlFile.close()

   return htmlData


#--------------------------------------------------------------
if __name__ == "__main__":

   # Test
   #*****************************
   __url = "http://gerold.bcom.at"
   #__webuser = "benutzername"
   #__webpass = "passwort"
   #print download_file(__url, __webuser, __webpass)
   print download_file(__url)
   #*****************************
mfg
Gerold
:-)

Verfasst: Montag 25. April 2005, 22:21
von BlackJack
Die vielen führenden Unterstriche verwirren mich etwas!?

Verfasst: Montag 25. April 2005, 22:37
von gerold
BlackJack hat geschrieben:Die vielen führenden Unterstriche verwirren mich etwas!?
Hi BlackJack!

Das ist so etwas wie eine Notlösung, damit ich beim Importieren dieses Moduls nicht automatisch auch urllib2 und base64 in der Codevervollständigung des WingIDE http://wingware.com/ habe.

Viel schlimmer ist aber, dass url, webuser und webpass auch aufscheinen würde, wenn ich die Unterstriche nicht machen würde.

Andernfalls hätte ich die Funktion in eine Klasse einschließen müssen und in anderen Programmen müsste ich mit "from download_file import Foo" arbeiten, was mir bei so kurzen Modulen nicht praktikabel erschien.

Ziel: Variablen und Imports des Modules sollen nicht nach außen hin sichtbar sein bzw. nicht unbedingt als PUBLIC erscheinen. Könnte man das anders lösen?

lg
Gerold
:-)

Verfasst: Montag 25. April 2005, 22:47
von gerold
gerold hat geschrieben: Ziel: Variablen und Imports des Modules sollen nicht nach außen hin sichtbar sein bzw. nicht unbedingt als PUBLIC erscheinen. Könnte man das anders lösen?
Ich würde ja gerne die Import-Anweisungen direkt in der Funktion machen, aber das gefällt den meisten nicht. Es macht zwar laut meinen Tests keinen messbaren Geschwindigkeitsunterschied, auch wenn ich in einem Modul hunderte Male das selbe Modul importiere, ... es wird ja nicht wirklich neu geladen.

Ich schreibe es mal um. Dann sieht man den Unterschied.

Verfasst: Montag 25. April 2005, 22:52
von gerold
So würde es anders aussehen. Import in der Funktion. Nach außen hin ist nur "download_file" und "modultest" sichtbar.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-


#--------------------------------------------------------------
def download_file(url, webuser = None, webpass = None):
    """
    Downloads a file
    """

    import urllib2
    import base64

    request =  urllib2.Request(url)

    if webuser:
        base64string = base64.encodestring('%s:%s' % (webuser, webpass))[:-1]
        request.add_header("Authorization", "Basic %s" % base64string)

    htmlFile = urllib2.urlopen(request)
    htmlData = htmlFile.read()
    htmlFile.close()

    return htmlData


#--------------------------------------------------------------
def main():
    # Test
    #*****************************
    url = "http://gerold.bcom.at"
    #webuser = "username"
    #webpass = "passwort"
    #print download_file(url, webuser, webpass)
    print download_file(url)
    #*****************************    


#--------------------------------------------------------------
if __name__ == "__main__":
    main()
lg
Gerold
:-)

Verfasst: Dienstag 26. April 2005, 22:22
von BlackJack
Bei der Funktion `modultest()` kannst Du die Unterstriche vor den Namen jetzt ja entfernen.

Um sie "pseudo-private" zu machen reicht auch 1 Unterstrich und ich weiss echt nicht warum es so schlimm ist, die importierten Module im Namensraum zu haben. Das ist völlig normal und man sieht das bei sehr vielen Modulen in der Standardbibliothek.

Es scheint, Du versuchst ein "Problem" von Deiner IDE damit zu umgehen.

Verfasst: Dienstag 26. April 2005, 22:54
von gerold
Hi BlackJack :)
BlackJack hat geschrieben: Bei der Funktion `modultest()` kannst Du die Unterstriche vor den Namen jetzt ja entfernen.
Habe ich soeben erledigt.
BlackJack hat geschrieben: Um sie "pseudo-private" zu machen reicht auch 1 Unterstrich und ich weiss echt nicht warum es so schlimm ist, die importierten Module im Namensraum zu haben. Das ist völlig normal und man sieht das bei sehr vielen Modulen in der Standardbibliothek.
Es scheint, Du versuchst ein "Problem" von Deiner IDE damit zu umgehen.
Wenn ich import download_file schreibe und später im Code download_file. (man achte auf den Punkt) eingebe, dann bietet mir WingIDE natürlich alles an, was ich über dieses Modul importiert habe. Das sehe ich jetzt nicht als "Problem" der IDE an, sondern eher als Feature. Dass teilweise wirklich viele Objekte in manchen Namensräumen rumschwirren, sieht man erst so recht, wenn man eine IDE verwendet, die den Namensraum nach verfügbaren Metoden, Variablen, usw. durchsucht.

Der Luxus besteht darin, eine kurze Liste als Hilfe beim Programmieren zu bekommen. Je größer die Liste wird, desto länger braucht man um diese Liste zu durchsuchen --> weniger Luxus :roll:

So schlecht ist Kapselung ja auch wieder nicht :)
Ich denke mal, dass ich mir das wieder angewöhnen werde, die Imports da zu machen wo ich sie brauche und nicht am Anfang des Moduls. Das habe ich mir gegen meine Überzeugung einreden lassen.

lg
Gerold
:-)

Verfasst: Mittwoch 27. April 2005, 06:05
von jens
Sollte man in WingIDE nicht dann einbauen, das er generell Python-Basis-Module/Objekte ignoriert?

Verfasst: Mittwoch 27. April 2005, 11:39
von gerold
jens hat geschrieben:Sollte man in WingIDE nicht dann einbauen, das er generell Python-Basis-Module/Objekte ignoriert?
Hi jens!

Aber das Verhalten von WingIDE ist absolut korrekt. Ich habe vom importierenden Modul aus, Zugriff auf die importierten Module des anderen Modules.

meintest.py:

Code: Alles auswählen

import string

my_var = "Ungeaendert"

def show_var():
   print "Aufruf aus meintest.py:", my_var
meintest2.py:

Code: Alles auswählen

import meintest

print meintest.string.center("Verwendung von 'string'", 40)
print meintest.my_var
meintest.my_var = "Geaendert"
print meintest.my_var
meintest.show_var()
Ergebnis:

Code: Alles auswählen

        Verwendung von 'string'         
Ungeaendert
Geaendert
Aufruf aus meintest.py: Geaendert
meintest2.py mit import*:

Code: Alles auswählen

from meintest import *

print string.center("Verwendung von 'string'", 40)
print my_var
my_var = "Geaendert"
print my_var
show_var()

Code: Alles auswählen

        Verwendung von 'string'         
Ungeaendert
Geaendert
Aufruf aus meintest.py: Ungeaendert
Zumindest wird bei from meintest import * die Variable my_var nicht geändert.

Meine Lösung:
- Kein oder wenig Code außerhalb von Funktionen
Ausnahme: if __name__ == "__main__": funktionsaufruf()
- Importiert wird da wo ich es brauche: in Funktionen, in Klassen, aber wenn möglich nicht in der obersten Ebene des Moduls.

So kann ich meine Namensräume sauber halten, was mir auch beim Programmieren ein sicheres Gefühl gibt. Wie ich schon schrieb: Ein wenig mehr Kapselung finde ich nicht schlecht.

lg
Gerold
:-)

Verfasst: Mittwoch 27. April 2005, 11:47
von jens
gerold hat geschrieben: Aber das Verhalten von WingIDE ist absolut korrekt. Ich habe vom importierenden Modul aus, Zugriff auf die importierten Module des anderen Modules.
Das mag ja sein, aber oben hast du dich beschwert das WingIDE zig Python-eigene-Module anbieten würde... Diese könnte man doch einfach rausfiltern.
gerold hat geschrieben:

Code: Alles auswählen

from meintest import *
*-Imports versuche ich allerdings immer zu vermeiden... Wenn ich mir fremden Code anschaue, ist es manchmal schwirieg festzustellen, wo was herkommt...

Verfasst: Mittwoch 27. April 2005, 12:12
von gerold
jens hat geschrieben: aber oben hast du dich beschwert das WingIDE zig Python-eigene-Module anbieten würde...
Hi Jens!

Sorry, das ist wohl falsch rüber gekommen.

lg
Gerold
:-)

Verfasst: Freitag 6. Mai 2005, 21:29
von globox
Ähm sorry aber wo läd er die datei überhapt hin?

Verfasst: Freitag 6. Mai 2005, 22:51
von gerold
globox hat geschrieben:Ähm sorry aber wo läd er die datei überhapt hin?
Hi!
Das mit dem Speichern funktioniert so:

Code: Alles auswählen

import download_file
f = file("xxx.html", "wb")
f.write(download_file.download_file("http://gerold.bcom.at"))
f.close()
mfg
Gerold
:-)

Verfasst: Samstag 7. Mai 2005, 00:38
von globox
Ach, hätt ich mir auch denken können :roll:
Danke :)