HTTP-Download

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
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Habe jetzt einiges im Code geändert.

Code: Alles auswählen

import requests
import json
from urllib.parse import urlsplit
from datetime import date


def build_local_filename(url, local_path):
    base, ext = os.path.splitext(os.path.basename(url))
    if os.path.isdir(local_path):
        filename = '{0:%Y-%m-%d}{1}'.format(date.today(), ext)
        local_path = os.path.join(local_path, filename)
    return local_path


def build_requests_post(url, user, passwd):
    data = {"login_act": user, "login_pwd": passwd}
    r = requests.post(url, data=json.dumps(data))
    try:
        r.raise_for_status()
    except requests.exceptions.HTTPError:
        print("Verbindungsfehler %s\nFehlercode: %s" % (url, r.status_code))
        return False
    return r


def http_download(url, user, passwd, local_path):
    """
    Stelle Verbindung zu HTTP-Server her, lade die Datei(en) herunter
    und speicher diese im Ordner import_suppliers_lists.
    """

    local_path = build_local_filename(url, local_path)
    url_split = urlsplit(url)
    base_url = "{0.scheme}://{0.netloc}/".format(url_split)
    path_url = os.path.dirname(url_split.path)
    file_url = os.path.basename(url_split.path)
    path = base_url[:-1]
    if build_requests_post(path, user, passwd):
        for step in path_url.split('/'):
            path = '{}{}/'.format(path, step)
            r = build_requests_post(path, user, passwd)
            try:
                print('headers: %s' % step, '\n', r.headers)
                print('cookies: %s' % step, '\n', r.cookies)
            except AttributeError:
                return False   # Muss noch geändert werden!
    with open(local_path, 'wb') as handle:
        for block in r.iter_content(1024):
            handle.write(block)

    if os.path.isfile(os.path.abspath(local_path)):
        return local_path
    return False

url = 'https://www.XXXXXX.de/Pricelist/10069/ENWPL136M4SO0T0MT78A56O/*.csv'
user = 'user'
passwd = 'passwd'
local_path = '/path/to/target'

http_download(url, user, passwd, local_path)
Bin ich da schon eher auf dem richtigen Weg?

Grüße Nobuddy

PS: Habe nachträglich nochmals Änderungen in der Furnktion 'http_download' vorgenommen.
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Meine letzte Code-Ausgabe, war nicht optimal und zu umständlich. Dies habe ich jetzt versucht zu ändern.
Ich habe 2 Ausgaben von Code erstellt.
Erstens den alten Code neu geschrieben und den zweiten Code, nach diesem Link
http://geophysik.uni-muenchen.de/~krisc ... anced.html gemacht. Den zweiten Code, werde ich der Übersicht halber nicht posten, da er genauso funktioniert wie Code 1 und die gleichen Fehlermeldungen nach URL-Path '~/Pricelist/' bringt.

Code 1:

Code: Alles auswählen

#!/usr/bin/python3
# -*- coding: utf-8

import os
import requests
import json
from urllib.parse import urlsplit
from datetime import date


class HTTP_Download(object):
    """
    Stelle Verbindung zu HTTP-Server her, lade die Datei(en) herunter
    und speichere diese im Ordner local_path.
    """

    def __init__(self, url, user, passwd, local_path):

        self.url, self.user, self.passwd, self.local_path = (url, user,
            passwd, local_path)
        self.local_path = self.build_local_filename()


    def build_local_filename(self):

        base, ext = os.path.splitext(os.path.basename(self.url))
        if os.path.isdir(self.local_path):
            filename = '{0:%Y-%m-%d}{1}'.format(date.today(), ext)
            self.local_path = os.path.join(self.local_path, filename)
        return self.local_path


    def http_download(self):

        url_split = urlsplit(self.url)
        base_url = "{0.scheme}://{0.netloc}/".format(url_split)
        data = {"login_act": user, "login_pwd": passwd}
        path = base_url[:-1]
        for step in url_split.path.split('/'):
            path = '{}{}'.format(path, step)
            if step != url_split.path.split('/')[-1]:
                path = '{}/'.format(path)
            r = requests.post(path, data=json.dumps(data))
            try:
                r.raise_for_status()
            except requests.exceptions.HTTPError:
                print("Verbindungsfehler %s\
                    \nFehlercode: %s" % (path, r.status_code))
        try:
            r.raise_for_status()
            with open(self.local_path, 'wb') as handle:
                for block in r.iter_content(1024):
                    handle.write(block)
            if os.path.isfile(os.path.abspath(self.local_path)):
                return self.local_path
        except requests.exceptions.HTTPError:
            print("Verbindungsfehler %s\
                \nFehlercode: %s" % (path, r.status_code))
        return False


if __name__ == '__main__':
    url = 'https://www.XXXXXX.de/Pricelist/10069/ENWPL136M4SO0T0MT78A56O/10069-XXXXXX-de-preisliste.csv'
    user = 'user'
    passwd = 'passwd'
    local_path = '/path/to/target'
    HTTP_Download(url, user, passwd, local_path).http_download()
Bis URL-Path '~/Pricelist/' erhalte ich 'status_code = 200'.
Ab URL-Path '~/10069/' erhalte ich 'status_code = 404' und kann somit den Download der Datei nicht einleiten.

Gehe ich über meinen Browser und bin im URL-Path 'https://www.XXXXXX.de/Pricelist/', sind dort zwei Buttons.
Der erste ist für den Download als csv-Datei, der zweite als xls-Datei.

Wie muss ich weiter vorgehen, um letztendlich die Datei herunterladen zu können?
Welche Informationen benötigt Ihr, um mir helfen zu können?

Grüße Nobuddy
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Habe jetzt die Lösung gefunden.
Nach dem Einloggen auf die Hauptseite, bin ich mit 'requests.post(base_url, data=json.dumps(data))', in jeden einzelnen Unterpfad gegangen. Darin liegt wahrscheinlich auch der Fehler.
Jetzt habe ich den Code so abgeändert, dass ich mich zuerst in die Hauptseite einlogge und dann anschließend die komplette URL in 'requests.post' verwende. Dies führt dann bei mir zu keinem Fehler und ich kann die Datei herunterladen. :D

Habe nochmals meinen Code optimiert.

Code: Alles auswählen

#!/usr/bin/python3
# -*- coding: utf-8

import os
import requests
import json
from urllib.parse import urlsplit
from datetime import date


class HTTP_Download(object):
    """
    Stelle Verbindung zu HTTP-Server her, lade die Datei(en) herunter
    und speichere diese im Ordner local_path.
    """

    def __init__(self, url, user, passwd, local_path):

        self.url, self.user, self.passwd, self.local_path = (url, user,
            passwd, local_path)
        base, ext = os.path.splitext(os.path.basename(self.url))
        if os.path.isdir(self.local_path):
            filename = '{0}{1}'.format(base, ext)
            self.local_path = os.path.join(self.local_path, filename)


    def http_download(self):

        url_split = urlsplit(self.url)
        base_url = "{0.scheme}://{0.netloc}/".format(url_split)
        data = {"login_act": user, "login_pwd": passwd}
       # Login Haupt-Internetseite
        r = requests.post(base_url, data=json.dumps(data))
        url_path = url_split
        try:
            r.raise_for_status()
           # Gehe zur Download-Datei
            r = requests.post(url, data=json.dumps(data), stream=True)
            url_path = url
            r.raise_for_status()
            with open(self.local_path, 'wb') as handle:
                for block in r.iter_content(1024):
                    handle.write(block)
            if os.path.isfile(os.path.abspath(self.local_path)):
                return self.local_path
        except requests.exceptions.HTTPError:
            print("Verbindungsfehler %s\
                \nFehlercode: %s" % (url_path, r.status_code))
        return False


if __name__ == '__main__':
    url = 'https://www.XXXXXX.de/Pricelist/10069/ENWPL136M4SO0T0MT78A56O/10069-XXXXXX-de-preisliste.csv'
    user = 'user'
    passwd = 'passwd'
    local_path = '/path/to/target'
    HTTP_Download(url, user, passwd, local_path).http_download()
Was mich noch interessiert, wenn ich keine Konkrete Datei zum Download vorliegen habe, wie kann ich mir dann von dem Download-Ordner, die zur Auswahl stehenden Dateien auflisten und ausgeben lassen?

Grüße Nobuddy
Antworten