Datei aus dem Internet herunterladen (download_file.py)

Code-Stücke können hier veröffentlicht werden.
Antworten
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

(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
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BlackJack

Die vielen führenden Unterstriche verwirren mich etwas!?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

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
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

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.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

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
:-)
Zuletzt geändert von gerold am Freitag 1. September 2006, 08:26, insgesamt 3-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
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.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

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
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Sollte man in WingIDE nicht dann einbauen, das er generell Python-Basis-Module/Objekte ignoriert?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

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
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

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
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
globox
User
Beiträge: 20
Registriert: Freitag 6. Mai 2005, 14:50
Kontaktdaten:

Ähm sorry aber wo läd er die datei überhapt hin?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

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
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
globox
User
Beiträge: 20
Registriert: Freitag 6. Mai 2005, 14:50
Kontaktdaten:

Ach, hätt ich mir auch denken können :roll:
Danke :)
Antworten