IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Lire seulement un extrait d'un TXT zippé depuis un lien URL [Python 3.X]


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Bioinformaticien
    Inscrit en
    Septembre 2021
    Messages
    55
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Bioinformaticien
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2021
    Messages : 55
    Par défaut Lire seulement un extrait d'un TXT zippé depuis un lien URL
    Bonjour à tous,


    Pour un programme je doit lire un fichier texte compressé (zip) disponible depuis un lien url.
    Le problème est que selon la date de dernière mise à jour du fichier, qui est présente dans les 5 premières lignes, je dois ou non lire tout le contenu. Comme c'est une gros fichier cela prend du temps dans mon script, c'est pour ça que j'aimerai trouver un moyen de ne lire qu'une petite partie du fichier pour d'abord récupérer cette date.

    Jusqu'à maintenant mon code, ci dessous, récupère, décompresse et lit tout le fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    import requests, zipfile, io
     
    r = requests.get(url)
    z = zipfile.ZipFile(io.BytesIO(r.content),'r')
    txtdata = z.read(z.namelist()[0])
    Lorsque le fichier est non compressé je sais utiliser la méthode chuck_size de requests pour n'en lire qu'une partie mais lorsqu'il est zippé je ne sais pas si cela est faisable..


    Merci d'avance pour vos propositions.

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 605
    Par défaut
    Regarde la doc de zipfile, et plus particulièrement sa méthode open.

    Tu peux lire le contenu d'un fichier à partir d'un fichier zip et tu dois pouvoir appliquer ce que tu fais lorsque tu veux n'en lire qu'une partie.

  3. #3
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 762
    Par défaut
    Citation Envoyé par ptrs32 Voir le message
    Lorsque le fichier est non compressé je sais utiliser la méthode chuck_size de requests pour n'en lire qu'une partie mais lorsqu'il est zippé je ne sais pas si cela est faisable..
    Techniquement, sans le répertoire qui se trouve à la fin du fichier, ZIP ne va pas en vouloir... mais vous pouvez lire le début du fichier en mode binaire pour essayer d'y retrouver les débuts de fichiers et en extraire l'information souhaitée.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 243
    Par défaut
    hello,
    la structure d'un fichier zip est celle-ci :
    Nom : StructFichierZip.png
Affichages : 110
Taille : 20,1 Ko

    Manque de chance les infos principales concernant les fichiers se trouvent à la fin du fichier zip dans la zone Central Directory et si on n'arrive pas à lire la signature de cette zone le fichier zip est jugé corrompu donc illisible. Donc on ne pourra pas utiliser infolist si on n'a pas la fin du fichier. Mais comme on peut le constater pour chaque fichier il y a un entête . Je n'ai pas trouvé de fonction qui vienne lire cet entête (cela existe peut-être). Voilà comment se présente cet entête :
    structFileHeader = "<4s2B4HL2L2H"
    stringFileHeader = b"PK\003\004"
    sizeFileHeader = struct.calcsize(structFileHeader)


    _FH_SIGNATURE = 0
    _FH_EXTRACT_VERSION = 1
    _FH_EXTRACT_SYSTEM = 2
    _FH_GENERAL_PURPOSE_FLAG_BITS = 3
    _FH_COMPRESSION_METHOD = 4
    _FH_LAST_MOD_TIME = 5
    _FH_LAST_MOD_DATE = 6
    _FH_CRC = 7
    _FH_COMPRESSED_SIZE = 8
    _FH_UNCOMPRESSED_SIZE = 9
    _FH_FILENAME_LENGTH = 10
    _FH_EXTRA_FIELD_LENGTH = 11

    Donc en se synchronisant sur la signature et en lisant le fichier en binaire , on peut arriver à lire cet entête si il est compris dans la partie du fichier zip que l'on récupère.
    Par chance, lorsqu'il n'y a qu'un seul fichier zippé , l'entête se trouve au début du fichier zip et donc en récupérant un minimum du fichier zip (1K par exemple) on a la possibilité de lire l'entête.
    Voici un code qui lit une partie d'un fichier zip (1K) avec un seul fichier pour avoir les infos du premier fichier et qui lit les infos des fichiers du fichier zip entier .
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    import datetime
    import zipfile
    import struct
    from datetime import date, timedelta,time
    _fileHeaderSize = struct.calcsize(zipfile.structFileHeader)
     
     
    def print_info(archive_name):
        print('lecture par infolist')
        zf = zipfile.ZipFile(archive_name)
        for info in zf.infolist():
            print(info.filename)
            print('\tComment:\t', info.comment)
            print('\tModified:\t', datetime.datetime(*info.date_time))
            print('\tSystem:\t\t', info.create_system, '(0 = Windows, 3 = Unix)')
            print('\tZIP version:\t', info.create_version)
            print('\tCompressed:\t', info.compress_size, 'bytes')
            print('\tUncompressed:\t', info.file_size, 'bytes')
            print('=====================================')
     
     
    def lireHeaderFile(zipFile):
        f = open(zipFile, 'r+b')
        data = f.read()
        pos = data.find(b'\x50\x4b\x03\x04') # début file header
        if pos >= 0:
            f.seek(pos)
            fheader = f.read(_fileHeaderSize)
            fheader = struct.unpack(zipfile.structFileHeader, fheader)
            fname = f.read(fheader[zipfile._FH_FILENAME_LENGTH])
            ftime = fheader[zipfile._FH_LAST_MOD_TIME]
            fdate = fheader[zipfile._FH_LAST_MOD_DATE]
            fcompsize = fheader[zipfile._FH_COMPRESSED_SIZE]
            ftotalsize = fheader[zipfile._FH_UNCOMPRESSED_SIZE]
            print("lecture par entête fichier local")
            print(fname)
            print('date : ',str(fdate & 0x001F),'/',str(fdate>>5 & 0x000F),'/',str((fdate>>9) + 1980))
            print('heure : ',str(ftime>>11),':',str(ftime>>5 & 0x001F),':',str((ftime & 0x001F) * 2))
            print('taille compressée : ',str(fcompsize))
            print('taille : ',str(ftotalsize))
            print('=======================================')
            f.close()
     
     
    if __name__ == '__main__':
        lireHeaderFile('d:/temp/partofExample.zip')
        print_info('d:/temp/Example.zip')
    et voici ce que j'obtiens :
    lecture par entête fichier local
    b'REF_CP_VILLE.txt'
    date : 18 / 2 / 2015
    heure : 15 : 5 : 42
    taille compressée : 977353
    taille : 3071406
    =======================================
    lecture par infolist
    REF_CP_VILLE.txt
    Comment: b''
    Modified: 2015-02-18 15:05:42
    System: 0 (0 = Windows, 3 = Unix)
    ZIP version: 63
    Compressed: 977353 bytes
    Uncompressed: 3071406 bytes
    =====================================
    On peut constater que l'on récupère les mêmes infos.
    Je ne suis pas sûr que ma méthode pour lire la date et l'heure dans le fichier zip qui sont en format msdos soit optimal. Il y a peut-être un module ou une fonction python qui le fait.
    La structure date time msdos est celle-ci :
    [in] wFatDate


    The MS-DOS date. The date is a packed value with the following format.


    PARAMETERS
    Bits Description
    0-4 Day of the month (1–31)
    5-8 Month (1 = January, 2 = February, and so on)
    9-15 Year offset from 1980 (add 1980 to get actual year)
    [in] wFatTime


    The MS-DOS time. The time is a packed value with the following format.


    TABLE 2
    Bits Description
    0-4 Second divided by 2
    5-10 Minute (0–59)
    11-15 Hour (0–23 on a 24-hour clock)
    Ami calmant, J.P

  5. #5
    Membre confirmé
    Homme Profil pro
    Bioinformaticien
    Inscrit en
    Septembre 2021
    Messages
    55
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Bioinformaticien
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2021
    Messages : 55
    Par défaut
    Merci à tous pour vos réponses,

    Citation Envoyé par wiztricks Voir le message
    Techniquement, sans le répertoire qui se trouve à la fin du fichier, ZIP ne va pas en vouloir... mais vous pouvez lire le début du fichier en mode binaire pour essayer d'y retrouver les débuts de fichiers et en extraire l'information souhaitée.
    - W
    J'arrive à extraire le début du document en 'bytes' mais lorsque je veux le décoder avec data.decode('UTF8') il n'y arrive pas.
    Ça vient surement du fait que les données sont toujours "compressées" et comme je n'ai pas le contenu entier du fichier il ne comprend pas que c'est un fichier zip donc impossible de le décompresser avec zlib.decompress(l)...

    Mon code actuellement pour récupérer le début en 'bytes':
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    r = requests.get(url, stream = True)
    for chunk in r.iter_content(chunk_size=516):
        bytes_data = chunk
        break

  6. #6
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 243
    Par défaut
    hello,
    Pourquoi fais-tu un data.decode("utf-8") ? tes datas ne sont pas du texte mais des données binaires. Regardes le code de LireHeaderFile de mon message précédent et le data.find

    Ami calmant, J.P

  7. #7
    Membre confirmé
    Homme Profil pro
    Bioinformaticien
    Inscrit en
    Septembre 2021
    Messages
    55
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Bioinformaticien
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2021
    Messages : 55
    Par défaut
    Citation Envoyé par jurassic pork Voir le message
    hello,
    Pourquoi fais-tu un data.decode("utf-8") ? tes datas ne sont pas du texte mais des données binaires. Regardes le code de LireHeaderFile de mon message précédent et le data.find

    Ami calmant, J.P
    Pourtant c'est ce que je trouve tout le temps pour convertir des données binaires en string. Voici un extrait des données :
    b"PK\x03\x04\x14\x00\x08\x08\x08\x00\xca\x0boS\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00alpha.v3.txt\xd4}\xc9\x8e\xeb\xba\x92\xe0Z\x05\xd4?\x14j\xf96\x99\x9e\x9dw\xa7Y\x90Zj\xc3\xb3\xfd\xff\x1f\xd2bL\x0c\x8a\xa4l\x9f\xe1U5p\xe0\x93\xa28\x89\x0c\x06c\x8e\xff\xfe?\xe9\xe9\xfc_\x97C\x91\x9e\xcb\xe2\x9f\xffZ,\xbe\x16\x9b\xaf\xe5\xe2\xbf\xff\xf3?\xfe\x95\xe4\xff\xb7(\x93\xd3%;?\x0e\xe5\x7f\xfe\xc7\x7f\xfeG\x92\xa6\xc9\xf7\xe2\xeb{\xf9\xf5\xbd\xfa\xfa\xde\x98\x82\x0c\x0b\xcc\x9f9\xfc\xb92\x7f\x16\xf0\xe7\xda\xfcY\xc2\x9fP\xb7\x82?\x7f\xcc\x9f5\xfc\xb95\x7f6\xf0\xe7\xce\xfc\xd9\xc2\x9f{\xf3gg\xfe\\@g=\xfc\t\x9d\r..."
    Et aussi ton code demande le pathway d'un fichier zip déjà téléchargé, moi il provient d'un URL et l'étape chronophage est lorsque je commence par récupérer les données de cet url avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    response = requests.get(url)
    C'est pour ça que je le réduit avec la méthode chuck_size qui me sort donc une partie des données en binaires ('bytes'), mais en théorie toujours compressées.

  8. #8
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 243
    Par défaut
    il faut adapter ma méthode pour une chaîne.

    voici un exemple de code qui va chercher les infos du premier fichier du zip https://www.python.org/ftp/python/3....mbed-win32.zip qui correspond à python.exe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    import requests
    import datetime
    import zipfile
    import struct
    from datetime import date, timedelta,time
    _fileHeaderSize = struct.calcsize(zipfile.structFileHeader)
    url="https://www.python.org/ftp/python/3.9.8/python-3.9.8-embed-win32.zip"
    response = requests.get(url, stream = True)
    data = b''
    for chunk in response.iter_content(chunk_size=200):
        data = chunk
        break
    pos = data.find(b'\x50\x4b\x03\x04') # début file header
    if pos >= 0:
        debheader = pos
        finheader = pos + _fileHeaderSize
        fheader = data[debheader:finheader]
        fheader = struct.unpack(zipfile.structFileHeader, fheader)
        fname = data[finheader:finheader + fheader[zipfile._FH_FILENAME_LENGTH]]
        ftime = fheader[zipfile._FH_LAST_MOD_TIME]
        fdate = fheader[zipfile._FH_LAST_MOD_DATE]
        fcompsize = fheader[zipfile._FH_COMPRESSED_SIZE]
        ftotalsize = fheader[zipfile._FH_UNCOMPRESSED_SIZE]
        print("lecture par entête fichier local")
        print(fname)
        print('date : ',str(fdate & 0x001F),'/',str(fdate>>5 & 0x000F),'/',str((fdate>>9) + 1980))
        print('heure : ',str(ftime>>11),':',str(ftime>>5 & 0x001F),':',str((ftime & 0x001F) * 2))
        print('taille compressée : ',str(fcompsize))
        print('taille : ',str(ftotalsize))
        print('=======================================')
    et voici le résultat :
    lecture par entête fichier local
    b'python.exe'
    date : 5 / 11 / 2021
    heure : 20 : 26 : 14
    taille compressée : 50842
    taille : 99560
    =======================================


  9. #9
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 762
    Par défaut
    Citation Envoyé par ptrs32 Voir le message
    Pourtant c'est ce que je trouve tout le temps pour convertir des données binaires en string.
    Ce n'est pas parce que çà se trouve tout le temps que c'est pertinent ici.

    Regardez la page Wikipédia qui traite du format ZIP, il y a des métadonnées binaires autour des données à décortiquer pour sortir les blocs de "vraies" données.... auxquelle on pourra éventuellement appliquer .decode s'il s'agit de texte.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Lire seulement le son contenu dans une AVI
    Par pointer dans le forum Delphi
    Réponses: 4
    Dernier message: 01/02/2007, 12h08
  2. lire du .wav et sauver en .txt
    Par guigui32 dans le forum Langage
    Réponses: 5
    Dernier message: 26/01/2007, 11h47
  3. [c#] lire seulement un caractère
    Par pepper18 dans le forum Windows Forms
    Réponses: 1
    Dernier message: 30/10/2006, 11h18
  4. Lire seulement le premier caractère
    Par quentingsc dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 12/08/2006, 20h41
  5. [VB6]Lire une partie d'un fichier .txt
    Par patoch76 dans le forum VB 6 et antérieur
    Réponses: 26
    Dernier message: 02/05/2006, 20h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo