Datei von Seite herunterladen #urlopen

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
mopmopen
User
Beiträge: 8
Registriert: Mittwoch 7. November 2012, 18:21

Guten Tag!

Ich war soweit immer ein stiller Mitleser dieses Boards und nun habe ich auch mal eine Frage, da ich mit meinem Latein am Ende bin.

Mein Problem zur Zeit ist ich möchte von einem Webserver diverse Daten runterladen, die man immer mit einen bestimmten Link und einer zusätzlichen Folge von Zeichen laden kann.

Das generieren des 6-stelligen Parts habe ich zur Zeit noch sehr Laienhaft umgesetzt in der Form von

Code: Alles auswählen

possible_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
a = b = c = d = e = f = 0
generated = ""
        generated = possible_chars[a] + possible_chars[b] + possible_chars[c] + possible_chars[d] + possible_chars[e] + possible_chars[f]
        if b == 35:
            a = a % 35 + 1
        if c == 35:
            b = b % 35 + 1
        if d == 35:
            c = c % 35 + 1
        if e == 35:
            d = d % 35 + 1
        if f == 35:
            e = e % 35 + 1
        f = f % 35 + 1
Aber mein eigentliches Problem liegt eher in diesem Part:

Code: Alles auswählen

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.19 (KHTML, like Gecko) Ubuntu/12.04 Chromium/18.0.1025.168 Chrome/18.0.1025.168 Safari/535.19'
try:
            url = urllib.request.urlopen(
                urllib.request.Request("url-link" + generated,
                    headers={'User-Agent': user_agent}))
            raw_data = url.read()
  
            if url.getcode() == 200:
                with open(generated + ".jpg", "wb") as output:
                    output.write(raw_data)
            else:
                continue
        except:
            continue
Wie man unschwer erkennen kann, speicher ich zur Zeit alles als eine .jpg Datei ab, welches aber oftmals nicht der Fall ist, so dass die Datei regelrecht im Sand verläuft.

Die Frage also an euch, wie könnte ich am besten herausfinden, was für eine Datei-Endung diese Datei hat, so dass ich sie richtig abspeichern kann.
Und für Anregungen zur Optimierung des generierten Terms wäre ich natürlich auch nicht abgeneigt ; )!

Mit freundlichen Gruß
mopmopen
BlackJack

@mopmopen: Zum ersten Problem schau Dir mal `combinations()` oder `permutations()` aus dem `itertools`-Modul an, je nach dem was Du da generierst.

Zum zweiten Problem könntest Du schauen ob in den Headern der Antwort vielleicht ein Dateiname oder ein MIME-Typ angegeben wird. Sonst müsstest Du anhand der Daten raten. Da gibt es glaube ich ein externes Modul was an dem Unix-Kommando ``magic`` angelehnt ist.
mopmopen
User
Beiträge: 8
Registriert: Mittwoch 7. November 2012, 18:21

Das mit den itertools kam mir auch schon in den Gedanken, muss ich mal schauen wie ich das stilvoll umsetzen kann.
Mein Ziel ist es halt von AAAAAA -> AAAAAB -> .. AAAABA etc durchzugehen.

Und zurück zu meinem eigentlichen Problem. Wenn ich den Link mit dem oberen Ausdruck aufrufe, verlinkt er mich danach direkt weiter und erhalte dann im Browser eine Endung in Form von:
....47b0183a.jpg?mime=1
Also es sollte eindeutig auslesbar sein, nur wie komme ich an diese URL?
Hab mich mit der API auseinandergesetzt aber partout nichts dafür gefunden.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo mopmop

in url.headers['Content-Type'] steht der Content-Type also image/jpeg für Bilder, text/html usw.

Zum Einfachen durchzählen aller Möglichkeiten:

Code: Alles auswählen

generate=lambda i,j=6: j>0 and generate(i/36,j-1)+"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"[i%36] or ""
generated=generate(1102632354)
Du willst nicht wirklich alle gut 2 Milliarden Kombinationen ausprobieren?

Grüße
Sirius
BlackJack

@Sirius3: Das „einfache” durchzählen sollte eher heissen: So nie in Produktivcode durchzählen. Das taugt nur zu Code-Golf oder -Obfuscation.

Code: Alles auswählen

from string import ascii_uppercase, digits

POSSIBLE_CHARS = ascii_uppercase + digits


def generate(number, length=6):
    result = list()
    for _ in xrange(length):
        number, index = divmod(number, len(POSSIBLE_CHARS))
        result.append(POSSIBLE_CHARS[index])
    return ''.join(reversed(result))


def main():
    print generate(958138143)


if __name__ == '__main__':
    main()
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@BlackJack: Ich habe schon als erste Lektion in Perl gelernt, dass alles was sich in eine Zeile Code schreiben läßt, verständlich, einfach, ausreichend dokumentiert und fehlerfrei ist. :twisted:
mopmopen
User
Beiträge: 8
Registriert: Mittwoch 7. November 2012, 18:21

Vielen dank für die Generierende-Funktion, das war genau das was ich gesucht habe!

Und ja es ist wirklich beabsichtigt, die 36^6 Möglichkeiten nach und nach zu generieren, desweiteren prüfe ich gerade ob es mit dem headers-funktioniert,
da ich mir ein wenig unsicher bin, was ich zurück bekomme, wenn es Richtung .pptx oder dergleichen geht.

Aber für Bilder und Video-Dateien scheint es schon einmal im Groben zu funktionieren, dafür bedanke ich mich schon einmal sehr!

Edit:
Erstes Problem zwecks Datei-Endung ist schon prompt aufgetreten.
Dateien mit einer '.zip'-Endung werden nur als 'octet-stream' erkannt, so dass ich nicht wirklich daraus schließen kann, das es eine Zip-Datei ist.
Also ist die Rangehensweise mit headers, leider nicht der 100% richtige Weg.

Hat eventuell jemand eine Idee, wie ich nach der "Weiterleitung" an die neue URL kommen kann?
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

mopmopen hat geschrieben:Und ja es ist wirklich beabsichtigt, die 36^6 Möglichkeiten nach und nach zu generieren,
Ehrlich? Hast Du Dir mal über die Laufzeit Gedanken gemacht - wie viele Requests schaffst Du denn so pro Sekunde?
mopmopen
User
Beiträge: 8
Registriert: Mittwoch 7. November 2012, 18:21

Dieses Skript wird generell über ein halbes Jahr benutzt, um eine gewisse Statistik zu ermitteln, was für Daten man findet, wie viele es generell sind
und eine mögliche Wachstumsprognose abgeben.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Wenn der/die Rechner über ein halbes Jahr 24/7 läuft/laufen, dann macht das ca. 140 Anfragen pro Sekunde. Ist durchaus im Bereich des Möglichen.
Das Leben ist wie ein Tennisball.
Antworten