Annonce

Réduire
Aucune annonce.

Lecture et analyse d'une page web, téléchargement de fichiers - COURS N°11

Réduire
Ceci est une discussion importante.
X
X
 
  • Filtre
  • Heure
  • Afficher
Tout nettoyer
nouveaux messages

  • Lecture et analyse d'une page web, téléchargement de fichiers - COURS N°11

    Lecture et analyse d'une page web, téléchargement de fichiers

    PROBLÉMATIQUE

    Ayant recherché des MP3's d'un groupe bien connu qui est les beatles, j'ai enfin trouvé mon bonheur en allant sur mon moteur de recherche préféré via une ligne très simple (pour les habitués).

    Code:
    intitle:"index of/" beatles mp3
    À partir de là je vais sur le lien de l'album que je recherche "With the beatles" et me retrouve à télécharger mes 14 titres de cet album.

    Seulement, bof ça me dit pas de faire cela 14 fois, je préfère me coder un petit programme qui me permettra de les télécharger les uns derrière les autres sans que j'ai à bouger le petit doigt (quelle fainéasse )

    Et en plus imaginons que j'en ai 250 à télécharger, vous le feriez 250 fois ?

    Pour faire cela, je dois passer par plusieurs étapes:
    1. Récupérer la page Web où se trouve mes MP3's
    2. Analyser cette page Web afin d'en ressortir le lien de chacun des MP3's
    3. Joindre l'url de base avec chaque lien
    4. Télécharger le MP3 et le placer dans un répertoire de votre choix sur votre disque dur



    Le code que je ferais, sera minimum, on pourrait prendre en compte plusieurs améliorations:
    • La gestion d'erreur (perte de réseau, ...)
    • L'utilisation des arguments de commande pour spécifier les extensions (mp3, avi, ...) qui nous intéressent, mais aussi pour aller plus loin les noms de fichiers, etc...
    • Une interface graphique


    et j'en passe...

    RÉCUPÉRATION DE LA PAGE WEB

    Cela nous permettra d'analyser par la suite la page afin d'en ressortir tous les liens de nos MP3's.

    Les modules python utiles sont:
    1. urllib.request et sa méthode read (dans la librairie standard)
    2. lxml (sudo apt-get install python3-lxml)


    lxml, c'est quoi ce module ? C'est le module extrêmement puissant dont les petits modules ou même gros comme scrapy s'appuient pour développer l'analyse des pages web.

    Oui mais là tu parles de récupération et non d'analyse, pourquoi lxml ?
    Simplement pour sa méthode fromstring, qui permettra de rendre le code HTML propre à partir d'une chaîne retournée par la méthode read du module urllib.request !

    Comme c'est simple, on est au cours n°11 on va placer le code avec quelques commentaires, ça devrait suffire à votre compréhension.

    Code:
    from urllib.request import urlopen
    from lxml import html # classe html pour travailler avec du HTML
    
    # URL dont tout va partir, on ajoutera nos urls de MP3 à celle-ci
    BASE_URL = "http://hcmaslov.d-real.sci-nnov.ru/public/mp3/Beatles/02%20With%20The%20Beatles/"
    
    # urlopen pour ouvrir la page, et read pour avoir le résultat sous forme de chaînes de caractères
    data = urlopen(BASE_URL).read()
    
    tree = html.fromstring(data) # pour rendre le code HTML propre
    tree sera l'arbre de recherche, mais on ne lui a pas dit encore ce qu'on recherchait...

    Ce qui nous donne un code HTML (code source de la page)

    Code:
    <html>
     <head>
      <title>Index of /public/mp3/Beatles/02 With The Beatles</title>
     </head>
     <body>
    <h1>Index of /public/mp3/Beatles/02 With The Beatles</h1>
      <table>
       <tr><th valign="top"><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr>
       <tr><th colspan="5"><hr></th></tr>
    <tr><td valign="top"><img src="/icons/back.gif" alt="[PARENTDIR]"></td><td><a href="/public/mp3/Beatles/">Parent Directory</a>                                                                                    </td><td> </td><td align="right">  - </td><td> </td></tr>
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2001%20It%20Won't%20Be%20Long%20.mp3">The Beatles - With The Beatles - 01 It Won't Be Long .mp3</a>                                           </td><td align="right">2004-02-11 21:10  </td><td align="right">2.5M</td><td> </td></tr>
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2002%20All%20I've%20Got%20To%20Do.mp3">The Beatles - With The Beatles - 02 All I've Got To Do.mp3</a>                                          </td><td align="right">2004-02-11 21:09  </td><td align="right">2.4M</td><td> </td></tr>
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2003%20All%20My%20Loving.mp3">The Beatles - With The Beatles - 03 All My Loving.mp3</a>                                               </td><td align="right">2004-02-11 21:12  </td><td align="right">2.5M</td><td> </td></tr>
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2004%20Don't%20Bother%20Me.mp3">The Beatles - With The Beatles - 04 Don't Bother Me.mp3</a>                                             </td><td align="right">2004-02-11 21:13  </td><td align="right">2.8M</td><td> </td></tr>
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2005%20Little%20Child.mp3">The Beatles - With The Beatles - 05 Little Child.mp3</a>                                                </td><td align="right">2004-02-11 21:13  </td><td align="right">2.1M</td><td> </td></tr>
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2006%20Till%20There%20Was%20You.mp3">The Beatles - With The Beatles - 06 Till There Was You.mp3</a>                                          </td><td align="right">2004-02-11 21:14  </td><td align="right">2.6M</td><td> </td></tr>
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2007%20Please%20Mister%20Postman.mp3">The Beatles - With The Beatles - 07 Please Mister Postman.mp3</a>                                       </td><td align="right">2004-02-11 21:13  </td><td align="right">3.0M</td><td> </td></tr>
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2008%20Roll%20Over%20Beethoven.mp3">The Beatles - With The Beatles - 08 Roll Over Beethoven.mp3</a>                                         </td><td align="right">2004-02-11 21:13  </td><td align="right">3.2M</td><td> </td></tr>
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2009%20Hold%20Me%20Tight.mp3">The Beatles - With The Beatles - 09 Hold Me Tight.mp3</a>                                               </td><td align="right">2004-02-11 21:13  </td><td align="right">2.9M</td><td> </td></tr>
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2010%20You%20Really%20Got%20A%20Hold%20On%20Me.mp3">The Beatles - With The Beatles - 10 You Really Got A Hold On Me.mp3</a>                                 </td><td align="right">2004-02-11 21:14  </td><td align="right">3.5M</td><td> </td></tr>
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2011%20I%20Wanna%20Be%20Your%20Man.mp3">The Beatles - With The Beatles - 11 I Wanna Be Your Man.mp3</a>                                         </td><td align="right">2004-02-11 21:13  </td><td align="right">2.3M</td><td> </td></tr>
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2012%20Devil%20In%20Her%20Heart.mp3">The Beatles - With The Beatles - 12 Devil In Her Heart.mp3</a>                                          </td><td align="right">2004-02-11 21:12  </td><td align="right">2.8M</td><td> </td></tr>
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2013%20Not%20A%20Second%20Time.mp3">The Beatles - With The Beatles - 13 Not A Second Time.mp3</a>                                           </td><td align="right">2004-02-11 21:13  </td><td align="right">2.4M</td><td> </td></tr>
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2014%20Money.mp3">The Beatles - With The Beatles - 14 Money.mp3</a>                                                       </td><td align="right">2004-02-11 21:13  </td><td align="right">3.3M</td><td> </td></tr>
       <tr><th colspan="5"><hr></th></tr>
    </table>
    </body></html>
    ANALYSE DE LA PAGE WEB

    La partie la plus complexe, souvent on y va à tâtons, mais avec l'expérience, votre patterns de recherche sera plus précis et vous devrez moins chercher.

    Donc analysons notre page HTML et regardons une ligne où se trouve l'url d'un MP3

    Code:
    <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2001%20It%20Won't%20Be%20Long%20.mp3">The Beatles - With The Beatles - 01 It Won't Be Long .mp3</a>
    En rouge j'ai mis tout ce dont j'ai besoin pour reconnaître et identifier tous mes MP3's, il faut qu'ils aient ces tags en communs et qu'ils contiennent le terme mp3.

    Ici c'est assez simple, pour commencer je vais utiliser la méthode xpath qui me permettra de faire une recherche par pattern.
    C'est le pattern qui est plus complexe à trouver, on prendre celui-ci : './/a[contains(text(), "mp3")]/@href' où on dit rechercher à la racine toutes les lignes où se trouvent la balise <a> comprenant le text (text()) mp3.

    Pour ce familiariser avec xpath, c'est les essais qui vous aideront, je me souviens avoir chercher au moins deux heures à comprendre son fonctionnement de pattern...

    //x -> recherche à la racine la balise x
    /x -> recherche la balise suivante x
    @x -> recherche toutes les valeurs de la propriété x

    Une fois familiarisé, on peut aller beaucoup plus loin, lxml est un module extrêmement puissant !

    Bref, après avoir fait plusieurs tests, j'arrive à ce code

    Code:
    elements = tree.xpath('.//a[contains(text(), "mp3")]/@href')
    Plus qu'à récupérer tous les liens de mes MP3's

    Code:
    for href in elements:
        print(href)
    Et là bingo!

    Code:
    The%20Beatles%20-%20With%20The%20Beatles%20-%2001%20It%20Won't%20Be%20Long%20.mp3
    The%20Beatles%20-%20With%20The%20Beatles%20-%2002%20All%20I've%20Got%20To%20Do.mp3
    The%20Beatles%20-%20With%20The%20Beatles%20-%2003%20All%20My%20Loving.mp3
    The%20Beatles%20-%20With%20The%20Beatles%20-%2004%20Don't%20Bother%20Me.mp3
    The%20Beatles%20-%20With%20The%20Beatles%20-%2005%20Little%20Child.mp3
    The%20Beatles%20-%20With%20The%20Beatles%20-%2006%20Till%20There%20Was%20You.mp3
    The%20Beatles%20-%20With%20The%20Beatles%20-%2007%20Please%20Mister%20Postman.mp3
    The%20Beatles%20-%20With%20The%20Beatles%20-%2008%20Roll%20Over%20Beethoven.mp3
    The%20Beatles%20-%20With%20The%20Beatles%20-%2009%20Hold%20Me%20Tight.mp3
    The%20Beatles%20-%20With%20The%20Beatles%20-%2010%20You%20Really%20Got%20A%20Hold%20On%20Me.mp3
    The%20Beatles%20-%20With%20The%20Beatles%20-%2011%20I%20Wanna%20Be%20Your%20Man.mp3
    The%20Beatles%20-%20With%20The%20Beatles%20-%2012%20Devil%20In%20Her%20Heart.mp3
    The%20Beatles%20-%20With%20The%20Beatles%20-%2013%20Not%20A%20Second%20Time.mp3
    The%20Beatles%20-%20With%20The%20Beatles%20-%2014%20Money.mp3
    JOINDRE MES URL'S

    Pour joindre l'url de base, souvenez-vous de la variable URL_BASE, on va utiliser un module exprès pour cela qui est urllib.parse et sa méthode urljoin.

    Code:
    url = urljoin(BASE_URL, href)
    Voilà url contient mon URL à télécharger, simple non?

    TÉLÉCHARGER LE MP3

    Pour télécharger l'url on va utiliser la méthode urlretrieve du module urllib.request

    Code:
    urlretrieve(url, "/home/fred1599/Musique/{}".format(titre))
    comme vous voyez j'ai une variable titre, car oui je trouve moche d'avoir enregistré un fichier sous cette forme

    Code:
    The%20Beatles%20-%20With%20The%20Beatles%20-%2014%20Money.mp3
    Je préfère

    Code:
    The Beatles - With The Beatles - 14 Money.mp3
    donc je vais remplacer ces %20 par un caractère d'espacement

    Code:
    titre = href.replace("%20", " ")
    et voilà, nous sommes arrivé à ce que nous voulions et le code final avec tout ça

    Code:
    from urllib.request import urlopen, urlretrieve
    from urllib.parse import urljoin
    from lxml import html
    
    BASE_URL = "http://hcmaslov.d-real.sci-nnov.ru/public/mp3/Beatles/02%20With%20The%20Beatles/"
    
    data = urlopen(BASE_URL).read()
    
    tree = html.fromstring(data)
    elements = tree.xpath('.//a[contains(text(), "mp3")]/@href')
    
    for count, href in enumerate(elements):
    	url = urljoin(BASE_URL, href)
    	titre = href.replace("%20", " ")
    	print("url n°{}: {}".format(count+1, titre))
    	urlretrieve(url, "/home/fred1599/Musique/{}".format(titre))
    Comme je l'ai dis c'est un code minimal pour vous faire connaître ce magnifique module qui est lxml...

    Merci de m'avoir lu et bonne journée...
    Dernière modification par fred, 19 août 2015, 13h01.

  • #2
    Bonsoir, merci pour ce tutoriel. J'aurai une petite question, comment faire pour "cliquer" sur un lien php en python ? Je ne sais pas si j'ai été clair :/
    Cordialement Vincauddu29

    Commentaire


    • #3
      Bonjour,
      quand tu effectues un clic, ton navigateur effectue une requête http derrière (GET ou POST), c'est cette requête que tu dois simuler avec python, pas un clic de souris

      Je te laisse chercher ça ou laisser Fred répondre en revanche sur la partie python

      Bonne soirée !
      Mon blog : http://rootsheep.info

      Commentaire


      • #4
        Merci de ta réponse

        Envoyé de mon Nexus 5 en utilisant Tapatalk

        Commentaire


        • #5
          Moi j'aurais utilisé wget
          WITHOUT DEVIATION FROM THE NORM, PROGRESS IS NOT POSSIBLE
          -Frank Zappa

          Commentaire


          • #6
            Moi j'aurais utilisé wget
            Effectivement tous les langages le permettent...

            Ce n'est pas portable
            Dernière modification par fred, 05 novembre 2015, 08h19.

            Commentaire


            • #7
              Merci pour vos réponses

              Envoyé de mon Nexus 5 en utilisant Tapatalk

              Commentaire


              • #8
                bonjours, merci pour le petit tuto sur xpath ça aide vraiment,mais j'ai une question,serait-il possible de faire la recherche de pattern avec les Regex?
                encore merci

                Commentaire


                • #9
                  bonjours, merci pour le petit tuto
                  Bonjour, en bas à gauche du topic concerné, tu as un bouton Thanks pour les remerciements

                  serait-il possible de faire la recherche de pattern avec les Regex?
                  Tout à fait, le moins laborieux et le plus rapide reste quand même lxml...

                  Code:
                  import re
                  
                  s = """
                  <tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]">\
                  </td><td><a href="The%20Beatles%20-%20With%20The%20Beatles%20-%2001%20\
                  It%20Won't%20Be%20Long%20.mp3">The Beatles - With The Beatles - 01 It\
                   Won't Be Long .mp3</a>
                   """
                  
                  PATTERN = '<a href="(The.+mp3)">?'
                  
                  res = re.findall(PATTERN, s)
                  print(res)
                  Idem pour trouver un pattern correct, c'est la pratique des regex qui rendra cela intuitif...

                  Bonne journée

                  Commentaire


                  • #10
                    bonjour Fred et à tous, j'ai fais un script comme celui de Fred mais sans lxml, avec l'exemple de reGex que tu m'as donné, le soucis est que ça me met un message d'erreur au niveau de urllretrieve
                    File "C:\Python34\lib\urllib\request.py", line 196, in urlretrieve
                    tfp = open(filename, 'wb')
                    PermissionError: [Errno 13] Permission denied: 'C:/Users/pytohs/desktop'

                    Commentaire


                    • #11
                      Cela peut avoir pour cause deux erreurs récurrentes de ce type de fonction appelés sur un path (chemin), comme par exemple en premier exécutez le script en tant qu'administrateur.

                      En effet,par défaut, les programmes n'ont pas la permission d'écrire dans Program Files et Program Files (x86). Enregistre le fichier ailleurs ou accorde à ton script les autorisations adéquates(par exemple, en exécutant en tant qu'administrateur).

                      Cela peut être aussi dû au chemin que tu a donné à filename, car tu a pu certainement essayé d'ouvrir un fichier dans le répertoire courant, pas dans le répertoire nommé par le chemin.Pour palier à ce genre de manière de montrer le chemin proprement à ta variable tu peux utiliser os.path.

                      Dans de rare cas, c'est une réécriture non-autorisé, ton fichier est créé mais tu n'a pas le droit de réécrire, mais je pense que tu devais en tenir compte au moment de l'écriture de ton script.

                      Voila si ça a pu t'aider de quelque sorte.
                      Dernière modification par DreAmuS, 18 novembre 2015, 10h16.

                      Commentaire


                      • #12
                        bonjour Fred et à tous, j'ai fais un script comme celui de Fred mais sans lxml, avec l'exemple de reGex que tu m'as donné, le soucis est que ça me met un message d'erreur au niveau de urllretrieve
                        File "C:\Python34\lib\urllib\request.py", line 196, in urlretrieve
                        tfp = open(filename, 'wb')
                        PermissionError: [Errno 13] Permission denied: 'C:/Users/pytohs/desktop'
                        Pourquoi as-tu besoin de urlretrieve ? Connais-tu son intérêt ? Ne confonds-tu pas avec urlopen ?

                        Commentaire


                        • #13
                          j'utilise Urlretrieve pour du telechargement, non je ne confonds pas les deux fonctions

                          mon soucis est que je voulais téléchargé un fichier sans préciser le type de fichier.du coup au lieux de faire ceci:
                          Code:
                          urlretrieve("http://site.com/image.jpeg","C:/Users/Pytohs/desktop/fichier_image.jpeg")
                          j'avais fais cela:
                          Code:
                          urlretrieve("http://site.com/image.jpeg","C:/Users/Pytohs/desktop")
                          merci DreAmuS, encore plus simple avec Os.path
                          Dernière modification par dramslinux, 18 novembre 2015, 21h51.

                          Commentaire


                          • #14
                            ok, avec windows je pense que tu dois faire plutôt r"C:\Users\Pytohs\desktop", comme j'ai pas de windows, je peux pas tester...

                            Commentaire


                            • #15
                              Je rejoint fred pour windows : http://stackoverflow.com/questions/9...rieve-succeeds

                              Depuis v3.4, python t'impose d'utiliser urllib ainsi :

                              regarde les / à la place \


                              chemin = r"C:\Users\Pytohs\desktop"

                              urllib2.urlretrieve("http://site.com/image.jpeg",chemin)


                              Par contre, et là encore daccord avec fred urlopen permet de voir les erreurs 404.

                              Voila
                              Dernière modification par DreAmuS, 19 novembre 2015, 10h49.

                              Commentaire

                              Chargement...
                              X