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 :

Extraction de données dans un doc xhtml


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 15
    Points : 12
    Points
    12
    Par défaut Extraction de données dans un doc xhtml
    Bonjour,

    Je souhaiterais a partir d"une page xhtml qui contient des liens vers tout un tas de package, écrire un script python qui me permette de construire une liste triée de la forme

    NOM_PACKAGE_1 URL_PACKAGE_1.
    NOM_PACKAGE_2 URL_PACKAGE_2

    Par exemple mon xhtml ressemble a ca :

    dload filename { url: 'http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-4.4.0-src.tar.bz2' }"
    href="/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-4.4.0-src.tar.bz2/download"
    title="/GCC Version 4/Current Release_ gcc-4.4.0/gcc-4.4.0-src.tar.bz2: released on 2009-06-23"
    >gcc-4.4.0-src.tar.bz2</a>

    </td>
    <td class="platform">


    </td>
    <td>62.7 MB</td>
    <td>2009-06-23</td>
    <td>3,274</td>
    <td>

    <a href="http://sourceforge.net/project/shownotes.php?release_id=691876" class="icon-sm notes-sm" title="Release Notes">Release Notes</a>

    </td>

    </tr>

    <tr id="node-775-2" class="child-of-node-753-1">

    <td class="tree">
    <a class="




    ext_jar

    dload filename { url: 'http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/ecj-20080701-src.jar' }"
    href="/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/ecj-20080701-src.jar/download"
    title="/GCC Version 4/Current Release_ gcc-4.4.0/ecj-20080701-src.jar: released on 2009-06-23"
    >ecj-20080701-src.jar</a>

    et je veux obtenir :

    ecj-20080701-src.jar http://downloads.sourceforge.net/pro...080701-src.jar
    gcc-4.4.0-src.tar.bz2 http://downloads.sourceforge.net/pro....0-src.tar.bz2


    ca implique de détecter dload filename { url:'URL_PACKAGE' }"
    et d'extraire URL_PACKAGE puis ensuite d'aller jusqu'au
    >NOM_PACKAGE<.

    Si vous savez faire ca faites moi signes...

    L'idée est de pouvoir lister les packages disponibles au téléchargement sur le site http://sourceforge.net/projects/mingw/files/.

    Rémunération possible par paypal ou rentacoder ...

  2. #2
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Bonsoir,


    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
    import urllib,re
     
    sock = urllib.urlopen('http://sourceforge.net/projects/mingw/files/')
    ch = sock.read()
    sock.close()
     
    pat = re.compile('(?<=dload filename { url)'
                     ": '(http://downloads.sourceforge.net/"
                     'project/mingw/GCC%20Version%204/'
                     'Current%20Release_%20gcc-4.4.0/'
                     "(.+?))'")
     
    liens = pat.findall(ch)
     
    print ('\n'+16*'-----'+'\n').join( v+'\n\n'+u for u,v in liens )


    Résultat:

    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     
    >>> 
    gcc-java-4.4.0-mingw32-bin-2.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-java-4.4.0-mingw32-bin-2.tar.gz
    --------------------------------------------------------------------------------
    gcc-full-4.4.0-mingw32-bin-2.tar.lzma
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-full-4.4.0-mingw32-bin-2.tar.lzma
    --------------------------------------------------------------------------------
    gcc-4.4.0-mingw32-src-2.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-4.4.0-mingw32-src-2.tar.gz
    --------------------------------------------------------------------------------
    pthreads-w32-2-8-0-src.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/pthreads-w32-2-8-0-src.tar.gz
    --------------------------------------------------------------------------------
    mpfr-2.4.1-src.tar.lzma
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/mpfr-2.4.1-src.tar.lzma
    --------------------------------------------------------------------------------
    gmp-4.2.4-src.tar.bz2
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gmp-4.2.4-src.tar.bz2
    --------------------------------------------------------------------------------
    gcc-4.4.0-src.tar.bz2
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-4.4.0-src.tar.bz2
    --------------------------------------------------------------------------------
    ecj-20080701-src.jar
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/ecj-20080701-src.jar
    --------------------------------------------------------------------------------
    pthreads-w32-2.8.0-mingw32-dll.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/pthreads-w32-2.8.0-mingw32-dll.tar.gz
    --------------------------------------------------------------------------------
    mpfr-2.4.1-mingw32-dll.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/mpfr-2.4.1-mingw32-dll.tar.gz
    --------------------------------------------------------------------------------
    gmp-4.2.4-mingw32-dll.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gmp-4.2.4-mingw32-dll.tar.gz
    --------------------------------------------------------------------------------
    gcc-4.4.0-mingw32-notes.txt
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-4.4.0-mingw32-notes.txt
    --------------------------------------------------------------------------------
    gcc-objc-4.4.0-mingw32-dll.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-objc-4.4.0-mingw32-dll.tar.gz
    --------------------------------------------------------------------------------
    gcc-objc-4.4.0-mingw32-bin.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-objc-4.4.0-mingw32-bin.tar.gz
    --------------------------------------------------------------------------------
    gcc-java-4.4.0-mingw32-dll.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-java-4.4.0-mingw32-dll.tar.gz
    --------------------------------------------------------------------------------
    gcc-fortran-4.4.0-mingw32-dll.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-fortran-4.4.0-mingw32-dll.tar.gz
    --------------------------------------------------------------------------------
    gcc-fortran-4.4.0-mingw32-bin.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-fortran-4.4.0-mingw32-bin.tar.gz
    --------------------------------------------------------------------------------
    gcc-core-4.4.0-mingw32-dll.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-core-4.4.0-mingw32-dll.tar.gz
    --------------------------------------------------------------------------------
    gcc-core-4.4.0-mingw32-bin.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-core-4.4.0-mingw32-bin.tar.gz
    --------------------------------------------------------------------------------
    gcc-c%2B%2B-4.4.0-mingw32-dll.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-c%2B%2B-4.4.0-mingw32-dll.tar.gz
    --------------------------------------------------------------------------------
    gcc-c%2B%2B-4.4.0-mingw32-bin.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-c%2B%2B-4.4.0-mingw32-bin.tar.gz
    --------------------------------------------------------------------------------
    gcc-ada-4.4.0-mingw32-dll.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-ada-4.4.0-mingw32-dll.tar.gz
    --------------------------------------------------------------------------------
    gcc-ada-4.4.0-mingw32-bin.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-ada-4.4.0-mingw32-bin.tar.gz
    >>>





    Pourquoi est-ce que je mets (?<=dload filename { url) en tête de la RE au lieu de simplement dload filename { url ?



    Parce que j’ai déterminé les nombres d’occurences des caractères situés avant le premier dload filename et les nombres d’occurences des caractéres situés dans l’ensemble de la page par le programme suivant:

    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
    import urllib,re
    from operator import itemgetter
    from collections import defaultdict
     
    sock = urllib.urlopen('http://sourceforge.net/projects/mingw/files/')
    ch = sock.read()
    sock.close()
     
    d = defaultdict(int)
     
    x = ch .find('dload filename')
    for c in ch[0:x]:  d[c]+=1
    lid = d.items()
    lid.sort(key=itemgetter(1))
    print '\n'.join( repr(u)+'\t'+str(v) for u,v in lid )
    del d
     
    print '\n==================================\n'
     
    d = defaultdict(int)
     
    for c in ch:  d[c]+=1
    lid = d.items()
    lid.sort(key=itemgetter(1))
    print '\n'.join( repr(u)+'\t'+str(v) for u,v in lid )


    Il en ressort que ’:’ apparaît un nombre limité de fois:
    26 fois avant le premier dload filename
    2984 fois sur l’ensemble du texte

    Alors que pour ’d’ par exemple:
    331 fois avant le premier dload filename
    29587 dans toute la page

    Pour ’h’ c’est
    161 et
    7205.

    etc



    On peut donc s’attendre que faire chercher au moteur de regex la lettre ’d’ comme premier caractère de la chaîne recherchée serait plus long que de lui donner à réagir sur le caractère ’:’ puisqu’il devrait s’arrêter plus souvent sur un ’d’ , afin de vérifier s’il est suivi du reste de la RE , que de s’arrêter sur un ’:’



    Comme il y a des ’:’ ailleurs que dans la portion
    http://downloads.sourceforge.net
    il faut un moyen de repérer le bon.

    Avec (?<=dload filename { url) , le moteur de regex vérifie si ’:’ est précédé de dload filename { url chaque fois qu’il rencontre un ’:’ et uniquement quand il en rencontre un. C’est toujours moins fréquent pour lui que de chercher dload filename { url tout le long du texte.




    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
     
    >>> 
    'K'	1
    'Q'	1
    'Y'	1
    'X'	2
    '#'	3
    '*'	3
    'V'	3
    '$'	4
    'L'	4
    '7'	4
    'H'	5
    'P'	5
    '|'	5
    'q'	6
    'R'	7
    'O'	8
    '&'	8
    '4'	9
    '?'	9
    '['	9
    '{'	9
    'I'	9
    ']'	9
    '}'	9
    '5'	10
    'A'	10
    'z'	11
    '8'	12
    '%'	14
    'E'	14
    'U'	14
    '9'	15
    'k'	16
    'B'	16
    '3'	19
    'F'	19
    'D'	20
    'N'	20
    '!'	21
    '6'	24
    'T'	25
    '+'	26
    ':'	26
    'W'	27
    '1'	27
    'S'	28
    'M'	29
    'G'	30
    ','	34
    '('	36
    'C'	36
    ')'	36
    'x'	38
    '2'	39
    '\t'	40
    'j'	50
    'y'	52
    '0'	67
    'b'	76
    '_'	79
    ';'	85
    "'"	87
    'w'	93
    '.'	95
    'g'	105
    'v'	115
    'm'	130
    'f'	137
    '-'	138
    'u'	149
    'h'	161
    '='	208
    '>'	236
    '<'	237
    '/'	265
    'c'	268
    'p'	273
    'l'	274
    '"'	283
    'n'	303
    'd'	331
    'o'	382
    '\n'	387
    'r'	398
    's'	420
    'a'	449
    'i'	450
    't'	523
    'e'	568
    ' '	3252
     
    ==================================
     
    '@'	2
    'X'	2
    'J'	2
    '#'	3
    '*'	3
    '|'	5
    'Q'	5
    '$'	10
    'q'	12
    '['	15
    ']'	15
    '&'	23
    '!'	37
    'H'	41
    '\t'	53
    '('	58
    ')'	58
    'I'	97
    '+'	122
    ';'	134
    'D'	280
    'U'	475
    '?'	585
    'V'	687
    'K'	724
    ','	756
    'F'	799
    '{'	893
    '}'	893
    'A'	900
    'P'	923
    'L'	932
    'O'	1066
    'T'	1212
    'W'	1327
    'C'	1357
    'B'	1569
    'Y'	1781
    "'"	1877
    'G'	2039
    'k'	2206
    'v'	2402
    'x'	2445
    'N'	2565
    'y'	2785
    '_'	2864
    ':'	2984
    'R'	3139
    'E'	3335
    'j'	3348
    '6'	3480
    'M'	3537
    '8'	3686
    '7'	4039
    'z'	4321
    '%'	4504
    'b'	4836
    '5'	5085
    '4'	5232
    '9'	5758
    'S'	6061
    'u'	6679
    'h'	7205
    '3'	7906
    'w'	8508
    'p'	9654
    'g'	10613
    'f'	11261
    '='	11440
    'm'	15109
    'c'	18535
    '2'	19154
    '0'	19906
    '<'	20853
    '>'	20853
    'n'	20998
    '1'	21142
    '"'	21538
    'r'	24694
    '.'	26124
    'o'	26960
    'i'	27367
    'a'	28486
    'l'	28505
    'd'	29587
    '\n'	32390
    '/'	33953
    '-'	35763
    's'	36236
    't'	44201
    'e'	45350
    ' '	870255
    >>>

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    Waou la il est tard donc je n'ai pas le temps d'analyser tout le code mais j'ai rarement vu une réponse aussi complète et expliqué.
    Un grand merci pour avoir pris de ton temps pour rédiger cette réponse.
    Ca fait plaisir!

    UPDATE: je viens de lire tout le message finalement et une petite correction, en fait je voulais TOUS les packages disponibles (pas seulement commencant par gcc) a partir de la section All Files car sinon on aura des doublons.
    Et enfin je voudrais que la liste soit triée par ordre alphabétique :

    aaaa-mingw32-1.0 http://....
    bbbb-msys-1.0 http://....
    less-436-1-msys.RELEASE_NOTES http://...
    zzzzz-mingw32 http://...

    Mais a partir des infos que vous donnez je devrais pouvoir adapter et faire quelque chose.

    Autre question: est ce que vous maitrisez aussi bien les scripts shells, sed et awk ?

  4. #4
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    en fait je voulais TOUS les packages disponibles (pas seulement commencant par gcc)
    Mais il y sont bien tous, non ?
    Les 4,5 et 6 ièmes sont
    pthreads-w32-2-8-0-src.tar.gz
    mpfr-2.4.1-src.tar.lzma
    gmp-4.2.4-src.tar.bz2
    par exemple.





    La modif suivante fera ton affaire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    x = ch.find('All Files')
    x = x + ch[x:].find('dload filename { url')
    y = ch.rfind('dload filename { url') + 500
    liens = [ m.group(2,1) for m in pat.finditer(ch[x:y]) ]
    liens.sort()
     
    print ('\n'+16*'-----'+'\n').join( '\n\n'.join(el) for el in liens )


    liens est une liste de doublets
    Pour avoir les doublets dans le bon ordre, j’inverse les chaînes attrapées par les deux groupes.
    Pour cela , un petit group(2,1) et hop. Ce qui oblige à abandonner findall() et à utiliser finditer()
    J’attire ton attention sur l’éminente utilité de finditer() en général.


    sort() trie une liste.
    Sur une liste de doublets, elle trie d’après les premiers éléments des doublets.
    C’est pour cela que je préfère inverser les deux chaînes matchées dans chaque match.
    Sinon, on aurait dû trier par liens.sort(key=itemgetter(1)) [ 0 étant le premier élément, 1 est le second]
    Et itemgetter() doit être importée. Là pas besoin d’importer

    Remarquer aussi l’écriture différente '\n\n'.join(el) for el in liens puisque el est maintenant un doublet dans le bon ordre.







    Pour éviter de lister les liens des “Newest Files“ , il suffit de faire chercher la regex après les mots “All Files“ en déterminant la position x de ces mots dans le texte:
    x = ch.find('All Files')

    La valeur de ce x = ch.find('All Files') , c’est à dire la position du caractères ’A’ de “All Files“ dans le texte est 10649.
    Avant ce x il y a 26 fois le caractère ’:’.

    Heureusement, il n’y a pas d’autre expression “All Files“ dans le texte. Il y a seulement “all files“ dans la définition du bouton “View all files“, mais Python distingue les majuscules des minuscules.



    x = x + ch[x:].find('dload filename { url')
    La valeur de ce nouvel x , c’est à dire la position du premier 'dload filename { url' situé après “All Files“ est 22287.
    Avant ce 2ième x, il y a 41 fois le caractère ’:’.

    Cela présente donc un intérêt de calculer ce 2ième x car on peut faire démarrer la recherche par la regex deux fois plus loin dans le texte et en évitant 2 fois plus de caractères ’:’



    Il faut bien voir que l’intérêt est d’ailleurs double:

    - en faisant commencer la recherche à 22287 au lieu de 10649, on évite au moteur de regex 2 fois plus de caractères sur chacun desquels il doit rechercher s’il est égal à ’:’

    - on divise aussi par 2 le nombre d’occurences de ’:’ sur lesquelles il doit s’arrêter pour examiner si elles sont suivies de la suite de la RE, à savoir ’ ' h ttp ://downloads.sourceforge.net/project/mingw/GCC...etc’ (j'ai mis deux blancs pour que ca ne mette pas en lien)

    Du moins est-ce ainsi que je comprends le fonctionnement d’un moteur de regex

    La regex saute donc à une position optimisée pour commencer sa recherche.




    De même, faire arrêter la recherche à y = ch.rfind('dload filename { url') + 500
    évite 6849 caractères et 36 ’:’
    Ce n’est pas énorme mais c’est toujours ça.
    Le 500 qui est ajouté, c’est pour aller bien au delà de la fin du dernier lien qui doit être attrapé, ces liens ayant en gros une longueur de 150 caractères.



    Ce fignolage est justifié par le fait que la fonction find() trouve les motifs à une vitesse extrêmement élevée. Sinon on perdrait plus de temps à chercher les x et y qu’on en gagnerait à éviter des plages de caractères au moteur de regex.












    Je ne connais pas du tout shell et awk.
    J’ai étudié un peu sed qui me semble très intéressant mais je ne sais pas l’utiliser.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par eyquem Voir le message
    Mais il y sont bien tous, non ?
    Les 4,5 et 6 ièmes sont
    pthreads-w32-2-8-0-src.tar.gz
    mpfr-2.4.1-src.tar.lzma
    gmp-4.2.4-src.tar.bz2
    par exemple.
    Heu nan, ils n'y a que les packages en relation avec gcc. Par exemple il n'y a pas bash, xz, less, ...
    Mais c'est normal vu que la RE ne prends que des expressions avec GCC%20Version%204/ ...

    En fait il suffirait de matcher seulement url: 'http://downloads.sourceforge.net'
    J'ai essayé de modifier le code comme ca :

    pat = re.compile('(?<=dload filename { url)'
    ": '(http://downloads.sourceforge.net/"
    "(.+?))'")

    mais du coup j'obtiens :

    project/mingw/MSYS%20xz/xz-4.999.8beta_20090725git-1/xz-4.999.8beta_20090725git-1-msys-1.0.11-bin.tar.gz
    http ://downloads.sourceforge.net/project/mingw/MSYS%20xz/xz-4.999.8beta_20090725git-1/xz-4.999.8beta_20090725git-1-msys-1.0.11-bin.tar.gz

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par smartmobili Voir le message
    Heu nan, ils n'y a que les packages en relation avec gcc. Par exemple il n'y a pas bash, xz, less, ...
    Mais c'est normal vu que la RE ne prends que des expressions avec GCC%20Version%204/ ...

    En fait il suffirait de matcher seulement url: 'http://downloads.sourceforge.net'
    J'ai essayé de modifier le code comme ca :

    pat = re.compile('(?<=dload filename { url)'
    ": '(http://downloads.sourceforge.net/"
    "(.+?))'")

    mais du coup j'obtiens :

    project/mingw/MSYS%20xz/xz-4.999.8beta_20090725git-1/xz-4.999.8beta_20090725git-1-msys-1.0.11-bin.tar.gz
    http ://downloads.sourceforge.net/project/mingw/MSYS%20xz/xz-4.999.8beta_20090725git-1/xz-4.999.8beta_20090725git-1-msys-1.0.11-bin.tar.gz
    Bon finalement j'obtiens ca :

    def munge(pair):
    p1, p2 = pair
    return (p1.rsplit('/', 1)[1], p2)

    sock = urllib.urlopen('http://sourceforge.net/projects/mingw/files/')
    ch = sock.read()
    sock.close()

    pat = re.compile('(?<=dload filename { url)'
    ": '(http://downloads.sourceforge.net/"
    'project/mingw/'
    "(.+?))'")


    x = ch.find('All Files')
    x = x + ch[x:].find('dload filename { url')
    y = ch.rfind('dload filename { url') + 500
    liens = [ m.group(2,1) for m in pat.finditer(ch[x:y]) ]

    print('\n'.join(munge(liens[0])))
    for el in liens[1:]:
    print(16*'-----'+'\n%s' % '\n'.join(munge(el)))

    Mais j'ai un dernier problème car les noms de packages sont parfois encodés cad qu'au lieu de g++ j'ai des trucs du genre g%20%20.
    Normalement il faudrait appeler urllib.unquote mais je n'arrive pas a l'ajouter.

  7. #7
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Bonjour,

    Je n’ai pas remarqué jusqu’à hier soir que tu avais modifié ton message, car une modification ne fait pas remonter la file dans la liste.



    J’ai compris que j’étais allé trop vite pour proposer mes solutions.

    Il faut dire que j’avais un problème pour afficher la page <http://sourceforge.net/projects/mingw/files/>.
    Mon navigateur ne doit pas être complet, et il faudrait que je fasse une réinstallation, en tous cas mon ordinateur n’arrive pas à afficher certaines pages web.
    Pour la page qui nous intéresse, l’affichage se bloquait sur le haut et je ne pouvais pas descendre. Pas pratique du tout pour analyser une page web et son code source

    J’ai éliminé du code source certaines parties, notamment ce qui est relatif au bouton Download, et j’ai pu consulter la page de liens en entier, ce qui m’a permis de comprendre comment elle est organisée et qu’il n’y a effectivement pas que des liens GCC.

    Alors voilà le résultat:


    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
    import urllib,re
    from time import clock
     
    #sock = urllib.urlopen('http://sourceforge.net/projects/mingw/files/')
    #ch = sock.read()
    #sock.close()
     
    f = open('mingw.txt')
    ch = f.read()
    f.close()
     
    pat = re.compile("(?<=dload filename { url): '(http://"
                     "downloads.sourceforge.net/"
                     "project/mingw/.+/([^']+))")
     
    x = ch.find('All Files')
    x = x + ch[x:].find('dload filename { url')
    y = ch.rfind('dload filename { url') + 500
    liens = [ m.group(2,1) for m in pat.finditer(ch[x:y]) ]
    liens.sort()
     
    for i in xrange(0,872,4):
        print ('\n'+16*'-----'+'\n').join( '\n\n'.join(el) for el in liens[i:i+4] )
        raw_input('\n\n  ***  pause  ***\n\n')
     
    print '-- Fin du programme --'

    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    ChangeLog.mingw
     
    http://downloads.sourceforge.net/project/mingw/GCC%20Version%202/Current%20Release_%20gcc-2.95.3/ChangeLog.mingw
    --------------------------------------------------------------------------------
    MSYS-1.0.10.exe
     
    http://downloads.sourceforge.net/project/mingw/MSYS%20Base%20System/msys-1.0.10/MSYS-1.0.10.exe
    --------------------------------------------------------------------------------
    MSYS-1.0.10.odmp.bz2
     
    http://downloads.sourceforge.net/project/mingw/MSYS%20Base%20System/msys-1.0.10/MSYS-1.0.10.odmp.bz2
    --------------------------------------------------------------------------------
    MSYS-1.0.11.RELEASE_NOTES.txt
     
    http://downloads.sourceforge.net/project/mingw/MSYS%20Base%20System/msys-1.0.11/MSYS-1.0.11.RELEASE_NOTES.txt
     
     
      ***  pause  ***
     
     
    MSYS-1.0.11.exe
     
    http://downloads.sourceforge.net/project/mingw/MSYS%20Base%20System/msys-1.0.11/MSYS-1.0.11.exe
    --------------------------------------------------------------------------------
    MSYS-1.0.8.exe
     
    http://downloads.sourceforge.net/project/mingw/MSYS%20Base%20System/msys-1.0.8/MSYS-1.0.8.exe
    --------------------------------------------------------------------------------
    MSYS-1.0.9.exe
     
    http://downloads.sourceforge.net/project/mingw/MSYS%20Base%20System/msys-1.0.9/MSYS-1.0.9.exe
    --------------------------------------------------------------------------------
    MinGW-5.1.4-src.tar.gz
     
    http://downloads.sourceforge.net/project/mingw/Automated%20MinGW%20Installer/MinGW%205.1.4/MinGW-5.1.4-src.tar.gz
     
     
      ***  pause  ***
     
     
    MinGW-5.1.4.exe
     
    http://downloads.sourceforge.net/project/mingw/Automated%20MinGW%20Installer/MinGW%205.1.4/MinGW-5.1.4.exe
    --------------------------------------------------------------------------------
    MinGW-5.1.6.exe
     
    http://downloads.sourceforge.net/project/mingw/Automated%20MinGW%20Installer/MinGW%205.1.6/MinGW-5.1.6.exe
    --------------------------------------------------------------------------------
    MinGW-5.1.6.exe-src.tar.lzma
     
    http://downloads.sourceforge.net/project/mingw/Automated%20MinGW%20Installer/MinGW%205.1.6/MinGW-5.1.6.exe-src.tar.lzma
    --------------------------------------------------------------------------------
    SDL-1.2.8-mingwPORT.tar.bz2
     
    http://downloads.sourceforge.net/project/mingw/mingwPORT/Current%20Releases/SDL-1.2.8-mingwPORT.tar.bz2
     
     
     
     
      ***  pause  ***
     
     
     
    _G_config.h
     
    http://downloads.sourceforge.net/project/mingw/MSYS%20System%20Builder/Technology%20Preview_%20msysDVLPR-1.0.0-alpha-1/_G_config.h
    --------------------------------------------------------------------------------
    autoconf-2.59-mingwPORT.tar.bz2
     
    http://downloads.sourceforge.net/project/mingw/mingwPORT/Older%20Releases/autoconf-2.59-mingwPORT.tar.bz2
    --------------------------------------------------------------------------------
    autoconf-2.63-1-msys-1.0.11-bin.tar.lzma
     
    http://downloads.sourceforge.net/project/mingw/MSYS%20autoconf/autoconf-2.63-1/autoconf-2.63-1-msys-1.0.11-bin.tar.lzma
    --------------------------------------------------------------------------------
    autoconf-2.63-1-msys-1.0.11-doc.tar.lzma
     
    http://downloads.sourceforge.net/project/mingw/MSYS%20autoconf/autoconf-2.63-1/autoconf-2.63-1-msys-1.0.11-doc.tar.lzma
     
     
     
     
      ***  pause  ***
     
     
     
    autoconf-2.63-1-msys-1.0.11-lic.tar.lzma
     
    http://downloads.sourceforge.net/project/mingw/MSYS%20autoconf/autoconf-2.63-1/autoconf-2.63-1-msys-1.0.11-lic.tar.lzma
    --------------------------------------------------------------------------------
    autoconf-2.63-1-msys-1.0.11-src.tar.lzma
     
    http://downloads.sourceforge.net/project/mingw/MSYS%20autoconf/autoconf-2.63-1/autoconf-2.63-1-msys-1.0.11-src.tar.lzma
    --------------------------------------------------------------------------------
    autoconf-2.63-1-msys.RELEASE_NOTES
     
    http://downloads.sourceforge.net/project/mingw/MSYS%20autoconf/autoconf-2.63-1/autoconf-2.63-1-msys.RELEASE_NOTES
    --------------------------------------------------------------------------------
    autoconf-6-1-mingw32-bin.tar.lzma
     
    http://downloads.sourceforge.net/project/mingw/MinGW%20autoconf/wrapper/autoconf-6-1/autoconf-6-1-mingw32-bin.tar.lzma
     
     
     
     
      ***  pause  ***
     
     
    autoconf-6-1-mingw32-lic.tar.lzma
     
    http://downloads.sourceforge.net/project/mingw/MinGW%20autoconf/wrapper/autoconf-6-1/autoconf-6-1-mingw32-lic.tar.lzma
    --------------------------------------------------------------------------------
    autoconf-6-1-mingw32-src.tar.lzma
     
    http://downloads.sourceforge.net/project/mingw/MinGW%20autoconf/wrapper/autoconf-6-1/autoconf-6-1-mingw32-src.tar.lzma
    --------------------------------------------------------------------------------
    autoconf-6-1-mingw32.RELEASE_NOTES
     
    http://downloads.sourceforge.net/project/mingw/MinGW%20autoconf/wrapper/autoconf-6-1/autoconf-6-1-mingw32.RELEASE_NOTES
    --------------------------------------------------------------------------------
    autoconf-7-1-mingw32-bin.tar.lzma
     
    http://downloads.sourceforge.net/project/mingw/MinGW%20autoconf/wrapper/autoconf-7-1/autoconf-7-1-mingw32-bin.tar.lzma
     
     
     
     
      ***  pause  ***
     
     
    etc
    etc
    etc



    Explication de la partie .+/([^']+) de la RE:


    .+/ matche avec un segment de chaîne suivi du caractère / et comme + n’est pas suivi d’un ? qui limiterait son comportement glouton, ce segment est le plus long possible.

    Ou pourrait être le plus long possible s’il n’y avait pas [^’]+ qui suit.




    [^’] représente le caractère d’UNE position.

    Mais dans [^’] , les crochets spécifient que le caractère que [^’] représente ne se limite pas à un seul mais qu’il peut être un quelconque de ceux qui appartiennent à un certain ensemble. Entre crochets se trouve l’énumération des éléments (caractères) de cet ensemble.

    Ici l’ensemble est défini par complémentation: le premier caractère ^ est spécial, il indique que les caractères qui suivent n’appartiennent pas à l’ensemble.

    [^’] signifie donc : tous les caractères possibles et imaginables, sauf
    c'est a dire : le plus possible de caractères qui ne soient pas le caractère . Cela définit donc un segment borné par au bout (aprés).





    L’obligation de trouver un motif qui respecte simultanément ces deux conditions fait que le moteur de regex n’a d’autre possibilité que de trouver comme matching avec .+/[^']+ :
    le plus long segment de chaîne quelconque possible qui soit suivi d’un caractère / suivi lui même d’un segment dénué de caractère / qui se termine devant une apostrophe ’




    Comme on veut attraper le segment entre le dernier / et la première apostrophe ’ , on place entre parenthèses .+/([^']+)






    L’itération for i in xrange(0,872,4): fait afficher les résultats par groupes de 4 adresses de façon à pouvoir vérifier facilement la conformité des résultats.

    Pour obtenir les adresses selon leur ordre d’apparition dans la page web, il faut annuler la ligne liens.sort() qui les range par odre alphabétique de la fin d’adresse.



    Post scriptum

    Je n’ai pas lu en détail ton nouveau message que je viens de voir. Je préfère mettre cette réponse telle quelle avant de le regarder car je venais de terminer tout ça.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    Salut eyquem,

    J'aurais d'autres traitements dans le genre à effectuer, est ce que cela t'intéresserais de faire une mission rémunérée d'une journée ?
    Si c'est le cas n'hésites pas me contacter.

  9. #9
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    J’ai regardé ton code.
    Eh bien c’est pas mal, tu es arrivé à te débrouiller finalement.


    1) return(p1.rpartition('/')[2],p2) serait peut être un poil plus rapide, et en tous cas plus lisible.

    Je pense surtout qu’il est superflu de passer à munge() chaque doublet en entier pour renvoyer la deuxième composante inchangée.
    Je préfère personnellement ne passer que la première composante de chaque tuple,
    et même, ne pas utiliser du tout de fonction munge()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    print(liens[0][0].rsplit('/',1)[1] + '\n' + liens[0][1])
    for u,v in liens[1:]:
     print(16*'-----' + '\n' + u.rsplit('/',1)[1] + '\n' + v)



    2) Concernant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    print('\n'.join(munge(liens[0])))
    for el in liens[1:]:
        print(16*'-----'+'\n%s' % '\n'.join(munge(el)))
    Réécrivons:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    li = [ '\n'.join(munge(el)) for el in liens ]
    print(li[0])
    for EL in li[1:]:
        print(16*'-----'+'\n%s' % EL)
    c’est à dire de façon équivalente:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    li = [ '\n'.join(munge(el)) for el in liens ]
    print(li[0])
    for EL in li[1:]:
        print(16*'-----'+'\n’ + EL)
    Je ne vois comme seule motivation de distinguer l’écriture de li[o] de celle des éléments suivants dans li[1:] que celle d’éviter d’avoir 16*'-----' avant li[0].

    Or la fonction join() est très intéressante parce qu’elle lie les éléments d’un itérable par un liant placé uniquement ENTRE les éléments.
    Ainsi ’***’.join([’a’,’b’,’c’,’d’]) renvoie
    a***b***c***d
    On peut donc remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    li = [ '\n'.join(munge(el)) for el in liens ]
    print(li[0])
    for EL in li[1:]:
        print(16*'-----'+'\n’ + EL)
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    li = [ '\n'.join(munge(el)) for el in liens ]
    (16*'-----'+'\n’).join(li)
    c’est à dire par l’unique ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (16*'-----'+'\n’).join( '\n'.join(munge(el)) for el in liens)



    3) Ton code peut être rendu plus pythonien par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def munge(p1,p2):
        return (p1.rsplit('/', 1)[1], p2)
    
    print('\n'.join(munge(*liens[0])))
    for el in liens[1:]:
     print(16*'-----'+'\n%s' % '\n'.join(munge(*el)))


    cf pour explications 5.3 dans
    https://www.siafoo.net/article/52#pa...y-as-arguments





    4) Mon code doit êre amélioré sur un point

    Au lieu de faire créer ('\n'+16*'-----'+'\n') et de le perdre à chaque tour i parce qu’il est crée à la volée dans:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for i in xrange(0,872,4):
        print ('\n'+16*'-----'+'\n').join( '\n\n'.join(el) for el in liens[i:i+4] )
        raw_input('\n\n  ***  pause  ***\n\n')
    il vaut mieux créer l’objet '\n'+16*'-----'+'\n' une seule fois et le garder vivant en lui collant une référence dessus pour l’utiliser plusieurs fois:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    colle = '\n'+16*'-----'+'\n'
    for i in xrange(0,len(liens),4):
        print colle.join( '\n\n'.join(el) for el in liens[i:i+4] )
        raw_input('\n\n  ***  pause  ***\n\n')
    Au passage: len(liens)




    5) Certes une expression régulière fait parfaitement l’affaire.Mais tu as évoqué sed et ce n’est peut être pas à oublier. D’après ce que j’ai lu, sed serait même plus puissant que les expressions régulières. Mais sed se limite à ne traiter qu’une seule ligne à la fois, ce qui est le cas ici puisque chaque lien est dans une seule ligne. Peut être y aurait-il un intérêt à extraire les liens avec sed ??

    Le problème étant que je ne sais pas comment pourrait être exploité ce que renvoie sed: les résultats de traitements de lignes pourraient ils être assemblés dans une liste ?...

    Quant à awk et shell, je ne connais pas.

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

Discussions similaires

  1. extraction de données dans excel
    Par massilia80 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 23/10/2006, 12h14
  2. Extraction de données dans un fichier texte en VB6 !
    Par rockroa dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 21/06/2006, 16h00
  3. extraction des données dans une table Access
    Par moabomotal dans le forum Access
    Réponses: 2
    Dernier message: 26/05/2006, 11h17
  4. Extraction de donnés dans un fichier XML
    Par ANISSS dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 27/01/2006, 13h16
  5. insérer donnée dans un doc. word.
    Par roots_man dans le forum ASP
    Réponses: 5
    Dernier message: 20/12/2004, 13h09

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