Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Algo] Récupérer le texte d'une URL

Et la mettre dans un fichier texte

    30 mars 2011 à 19:30:27

    Bonjour à tou(te)s,

    Ma démarche est la suivante: Je viens chercher un coup de main dans l'élaboration de l'algorithme d'un programme, puis j'essaierai de le coder et je posterai mon résultat (ou un peu avant si je n'arrive pas à résoudre mes soucis de programmation) dans le but d'avancer par moi même au maximum.


    Alors, mon but est le suivant:

    J'ai:

    Une url de base qui ne change pas (par exemple: http://www.chezmoi.com/description=").
    Un fichier texte contenant des références (du genre "ABBAC"). Il y a une référence par ligne.
    Un fichier texte vierge.

    Je dois:

    Parcourir mon fichier texte ligne par ligne pour récupérer la référence. Ajouter cette référence à mon url de base (donc http://www.chezmoi.com/description=ABBAC par exemple). Copier le texte contenu dans la page web de l'url en question dans mon fichier texte vierge, mettre deux ou trois retour chariot pour bien séparer le texte des différentes références.
    Passer à la référence suivante, et faire de même.


    J'ai bien l'idée, mais c'est les fonctions que j'ai pas... =/ Je n'ai encore jamais manié d'url en python. La gestion des fichiers ça devrait aller, mais la lecture ligne à ligne ça pose problème...

    Auriez-vous pour commencer, quelques pistes de réflexions (des noms de fonction par exemple) qui m'aiderai à élaborer mon algorithme, ou des problèmes qui vont se poser.


    Par avance merci de votre participation et de votre aide.
    N'hésitez pas à demander plus de précisions car j'ai peur de ne pas être très clair.


    Cordialement,

    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      30 mars 2011 à 20:20:27

      Pour manipuler des urls, tu peux utiliser urlparse(), en version 3, c'est indiqué en haut de la page, le nom du module a changé.

      Pour l'ouverture de ton fichier et le traitement ligne par ligne, tu peux utiliser

      with open(tonfichier.txt) as f:
          for line in f:
              #traitement de tes lignes
      


      • Partager sur Facebook
      • Partager sur Twitter
        30 mars 2011 à 21:23:40

        Merci de ta réponse fred1599,

        Dans le coup, j'ai (je pense) toutes les données pour mener à bien mon projet, j'essaye de coder tout ça et je vous poste le code en vue d'amélioration, d'optimisation, ou au pire, une résolution d'erreur de programmation.

        Encore merci pour ton aide.


        P.S: Oui, je code en Python 3
        • Partager sur Facebook
        • Partager sur Twitter
          31 mars 2011 à 23:02:28

          Bonsoir,

          J'ai légèrement avancé (enfin j'espère), pour l'instant, j'ai codé ceci:

          import urllib
          
          fichierRef = open('ref.txt', 'r')      # On ouvre le fichier des références en lecture
          fichierDesc = open('description', 'w') # On ouvre le fichier des descriptions en écriture
          espace = "---------------------------------------------------------------------"
          
          ligneRef = fichierRef.readline()
          while ligneRef != "":
              page = urllib.urlopen('http://www.monurldebase.fr/description=' + str(ligneRef))
              fichierDesc = page.read()
              fichierDesc.write(espace)
          


          @fred1599, je n'ai pas trouvé d'utilité quand à urlparse(), j'ai regardé ici et j'ai vu aucun rapport quand à l'extraction du texte d'une page web.
          Qu'est-ce qui va, qu'est-ce qui va pas ?

          P.S: Je ne peux pas tester, car j'ai pas encore l'url en question =/
          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            31 mars 2011 à 23:22:10

            je t'ai proposé urlparse() en effet pas pour extraction d'une page web, mais pour je cite

            Citation

            Ajouter cette référence à mon url de base (donc http://www.chezmoi.com/description=ABBAC par exemple).



            Edit : Par exemple urlparse.urljoin() est utile lorsqu'on a besoin de beaucoup d'URL voisines.

            >>> ref = ['ABBAC', 'BCDEF', 'KGBJU']
            >>> for i in ref:
            ...     urljoin('http://www.chezmoi.com/description=', '/description=%s' %i)
            ... 
            'http://www.chezmoi.com/description=ABBAC'
            'http://www.chezmoi.com/description=BCDEF'
            'http://www.chezmoi.com/description=KGBJU'
            


            • Partager sur Facebook
            • Partager sur Twitter
              1 avril 2011 à 13:18:52

              Je suis arrivé à ceci:

              import urllib.request, urllib.parse
              
              
              fichierRef = open('ref.txt', 'r')      # On ouvre le fichier des références en lecture
              fichierDesc = open('description', 'w') # On ouvre le fichier des descriptions en écriture
              espace = "---------------------------------------------------------------------"
              
              ligneRef = fichierRef.readlines()
              for i in ligneRef :
                  page = urllib.parse.urljoin('http://www.chezmoi.com/description=', '/description=%s' %i)
                  fichierDesc = (urllib.request.urlopen(page).read())
                  fichierDesc.write(espace)
              


              Ca me sort beaucoup d'erreur, mais aucune dans mon fichier source mise à part une (ligne 11 sur le code ci dessus) qui pourtant me semble correcte (attention, je n'ai pas l'url donc je l'ai compilé "pour voir")


              Traceback (most recent call last):
                File "recuperation_description.py", line 16, in <module>
                  fichierDesc = (urllib.request.urlopen(page).read())
                File "/usr/lib/python3.1/urllib/request.py", line 121, in urlopen
                  return _opener.open(url, data, timeout)
                File "/usr/lib/python3.1/urllib/request.py", line 350, in open
                  response = self._open(req, data)
                File "/usr/lib/python3.1/urllib/request.py", line 368, in _open
                  '_open', req)
                File "/usr/lib/python3.1/urllib/request.py", line 328, in _call_chain
                  result = func(*args)
                File "/usr/lib/python3.1/urllib/request.py", line 1110, in http_open
                  return self.do_open(http.client.HTTPConnection, req)
                File "/usr/lib/python3.1/urllib/request.py", line 1092, in do_open
                  h.request(req.get_method(), req.selector, req.data, headers)
                File "/usr/lib/python3.1/http/client.py", line 940, in request
                  self._send_request(method, url, body, headers)
                File "/usr/lib/python3.1/http/client.py", line 968, in _send_request
                  self.putrequest(method, url, **skips)
                File "/usr/lib/python3.1/http/client.py", line 841, in putrequest
                  self._output(request.encode('ascii'))
              UnicodeEncodeError: 'ascii' codec can't encode character '\ufeff' in position 17: ordinal not in range(128)


              EDIT: Chezmoi.com existe bel et bien, ce n'est pas du tout le site en rapport avec mon code, ce n'était qu'un exemple et je ne savais même pas que chezmoi.com existait.

              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                1 avril 2011 à 14:53:16

                Le code semble correct, je pense au contraire que le site n'existe pas, tu devrais tenter avec un site existant comme http://www.python.org par exemple.

                Bien sûr il faudra s'attendre à aucun résultat à cause de cette ligne qui ne renvoi rien.

                fichierDesc = (urllib.request.urlopen(page).read())
                


                Il est aussi possible que la page internet où tu souhaites te connecter n'est pas en UTF8 d'où le problème

                UnicodeEncodeError: 'ascii' codec can't encode character '\ufeff' in position 17: ordinal not in range(128


                Encore une fois je te conseillerais un autre site, avec des références correctes.

                Edit : Waouhhh, j'ai dû fumer quand j'ai dis que ton code était correct :lol:

                Non c'est pas comme ceci qu'on écrit dans un fichier texte.

                fichierDesc = open('description', 'a')
                for i in ligneRef :
                    page = urllib.parse.urljoin('http://www.chezmoi.com/description=', '/description=%s' %i)
                    data = (urllib.request.urlopen(page).read())
                    fichierDesc.write(data+'\n')
                    fichierDesc.write(espace+'\n')
                


                Attention code non testé, et j'ai juste modifié quelques lignes.
                • Partager sur Facebook
                • Partager sur Twitter
                  1 avril 2011 à 18:36:21

                  Je te remercie énormément pour ton aide fred1599, dès que j'ai l'url (ce soir normalement) je me penche sur le code et je te tiens au courant :)

                  P.S: Il faut forcément stocker le texte du web dans une variable ? On peut pas faire ça "en direct" comme j'ai maladroitement essayé de le faire ?

                  En ce qui concerne l'encodage, la fonction

                  decode("l'encodage en question")
                  

                  serait judicieux ?
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    1 avril 2011 à 18:46:40

                    Citation

                    P.S: Il faut forcément stocker le texte du web dans une variable ?



                    Pas forcément, mais tu remarqueras que mon code ne fait pas la même chose, ce que tu proposes n'est pas correcte.

                    On peut bien entendu factoriser le code, ce qui agrandit la ligne de code en question, mais se serait moche.

                    fichierDesc.write(urllib.request.urlopen(page).read()+'\n')
                    


                    n'est-ce pas?

                    Citation

                    decode("l'encodage en question")



                    J'ai jamais trop maîtrisé, il faut y aller à taton, je bidouille souvent dans ce genre de cas, à toi de tester, en général après quelques essais, on trouve le bon résultat.

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Anonyme
                      1 avril 2011 à 20:16:24

                      Citation : LeChat

                      En ce qui concerne l'encodage, la fonction

                      decode("l'encodage en question")
                      


                      serait judicieux ?



                      Oui, et tu obtiens le bon encodage ainsi :

                      file.getheader('Content-Type').split('charset=')[1]
                      


                      ;)
                      • Partager sur Facebook
                      • Partager sur Twitter
                        2 avril 2011 à 12:19:04

                        Bon, je suis toujours dans l'impasse:

                        import urllib.request, urllib.parse
                        
                        
                        fichierRef = open('ref.txt', 'r')     
                        fichierDesc = open('description', 'w')
                        espace = "---------------------------------------------------------------------"
                        
                        ligneRef = fichierRef.readlines()
                        for i in ligneRef : #on parcourt les ref ligne à ligne 
                            page = urllib.parse.urljoin('http://www.europ-computer.com/produits/article_', '/article_%s' %i) 
                            fichierDesc = (urllib.request.urlopen(page).read()) 
                            fichierDesc = decode("iso-8859-1")
                            fichierDesc.write(espace)
                        


                        La compilation foire:

                        Python 3.1.2 (release31-maint, Sep 17 2010, 20:34:23) 
                        [GCC 4.4.5]
                        Type "help", "copyright", "credits" or "license" for more information.
                        >>> [evaluate recuperation_description.py]
                        Traceback (most recent call last):
                          Fichier "/usr/lib/wingide-101-4.0/src/debug/tserver/_sandbox.py", ligne 11, dans <module>
                          Fichier "/usr/lib/python3.1/urllib/request.py", ligne 121, dans urlopen
                            return _opener.open(url, data, timeout)
                          Fichier "/usr/lib/python3.1/urllib/request.py", ligne 350, dans open
                            response = self._open(req, data)
                          Fichier "/usr/lib/python3.1/urllib/request.py", ligne 368, dans _open
                            '_open', req)
                          Fichier "/usr/lib/python3.1/urllib/request.py", ligne 328, dans _call_chain
                            result = func(*args)
                          Fichier "/usr/lib/python3.1/urllib/request.py", ligne 1110, dans http_open
                            return self.do_open(http.client.HTTPConnection, req)
                          Fichier "/usr/lib/python3.1/urllib/request.py", ligne 1095, dans do_open
                            h.request(req.get_method(), req.selector, req.data, headers)
                          Fichier "/usr/lib/python3.1/http/client.py", ligne 940, dans request
                            self._send_request(method, url, body, headers)
                          Fichier "/usr/lib/python3.1/http/client.py", ligne 968, dans _send_request
                            self.putrequest(method, url, **skips)
                          Fichier "/usr/lib/python3.1/http/client.py", ligne 841, dans putrequest
                            self._output(request.encode('ascii'))
                        builtins.UnicodeEncodeError: 'ascii' codec can't encode character '\ufeff' in position 13: ordinal not in range(128)
                        >>>


                        Si quelqu'un peut m'éclairer sur la fonction decode. Là je récupère le texte et je le "decode" ensuite, est-ce correct ou est-ce qu'il faut le "décoder" en même temps que la fonction read ?

                        Et je ne comprends pas les erreurs de la compilation.... J'ai l'impression que l'erreur est dans les modules o_O A moins que je fasse une mauvaise utilisation de ces derniers.


                        Une dernière chose:

                        ligneRef = fichierRef.readlines()
                        


                        Ca transforme bien ligneRef en liste, et la boucle for i in ligneRef: parcours chaque membre de la liste, traite les opérations, et s'arrête à la fin de la liste, c'est correct ? Il n'y a pas besoin d'incrémenter i ? (je viens du C donc bon ^^')
                        • Partager sur Facebook
                        • Partager sur Twitter
                          2 avril 2011 à 13:00:37

                          Si c'est toujours cette ligne qui bogue :

                          fichierDesc = (urllib.request.urlopen(page).read())
                          

                          Essaie l'une de ces fonctions autour de la variable « page » : str(), encode(), decode(), ou urllib.parse.urlencode().

                          PS : Le code de ton programme est-il enregistré en Utf-8 ?
                          • Partager sur Facebook
                          • Partager sur Twitter
                            2 avril 2011 à 13:27:29

                            Ca avance un peu, la compilation ne crie plus sur la ligne urljoin, mais maintenant elle crie sur (urllib.request.urlopen(page).read())

                            #-*- coding: utf-8 -*-
                            import urllib.request, urllib.parse
                            
                            
                            fichierRef = open('ref.txt', 'r')      
                            fichierDesc = open('description', 'w') 
                            espace = "---------------------------------------------------------------------"
                            
                            ligneRef = fichierRef.readlines()
                            for i in ligneRef : 
                                page = urllib.parse.urljoin('http://www.europ-computer.com/produits/article_', '/article_%s' %i).encode('utf-8')
                                fichierDesc = (urllib.request.urlopen(page).read()) 
                                fichierDesc.write(espace)
                            


                            La compilation:

                            Traceback (most recent call last):
                              File "recuperation_description.py", line 12, in <module>
                                fichierDesc = (urllib.request.urlopen(page).read()) 
                              File "/usr/lib/python3.1/urllib/request.py", line 121, in urlopen
                                return _opener.open(url, data, timeout)
                              File "/usr/lib/python3.1/urllib/request.py", line 341, in open
                                req.timeout = timeout
                            AttributeError: 'bytes' object has no attribute 'timeout'


                            L'encodage est en utf-8 et le fichier est bien enregistrer en UTF-8, quand à la page web elle est encodé en iso-8859-1 mais le code ne veut pas de cet encodage, je cite (ceci dis, je comprends pas le rapport avec latin-1):

                            UnicodeEncodeError: 'latin-1' codec can't encode character '\ufeff' in position 38: ordinal not in range(256)


                            Je commence à désespérer et je me demande si le soucis ne se situe pas au niveau du site web en question.
                            P.S: Les ref ne contiennent pas le ".html" de la fin, ça peut jouer ?
                            • Partager sur Facebook
                            • Partager sur Twitter
                            Anonyme
                              2 avril 2011 à 13:35:09

                              Non mais t'as je pense toujours pas compris :)

                              Voilà un code fonctionnel, qui te permet simplement d'écrire dans un fichier le code source d'une page web.

                              import urllib.request, urllib.parse
                              
                              
                              fichierDesc = open('description', 'a')
                              espace = "---------------------------------------------------------------------"
                              
                              url = 'http://www.python.org'
                              data = (urllib.request.urlopen(url).read()) 
                              data = data.decode("iso-8859-1")
                              fichierDesc.write(data+'\n')
                              fichierDesc.write(espace+'\n')
                              


                              Tu ne peux pas ouvrir un fichier

                              fichierDesc = open('description', 'w')
                              


                              et donner la variable contenant l'objet fichier, l'affecter à une url

                              fichierDesc = (urllib.request.urlopen(page).read())
                              


                              vois-tu l'incohérence?

                              Quand tu crées un objet fichier, tu ne peux en gros que le lire ou l'écrire.

                              Quand tu te connectes à une url, tu ne pourras que lire une url (rien à voir avec l'objet fichier)

                              Citation

                              A moins que je fasse une mauvaise utilisation de ces derniers



                              Il n'y a pas de doute là dessus. ;)

                              Attention dans le choix de l'url, tu en as choisi une (j'ai testé) qui demande une authentification.

                              Je t'aurais bien donné un code complet, mais je pense qu'en tant que débutant, ça ne te rendrait pas service.

                              • Partager sur Facebook
                              • Partager sur Twitter
                                2 avril 2011 à 13:44:33

                                Donc en théorie si je fais ça:

                                import urllib.request, urllib.parse
                                
                                
                                fichierRef = open('ref.txt', 'r')      
                                fichierDesc = open('description', 'w') 
                                espace = "---------------------------------------------------------------------"
                                
                                ligneRef = fichierRef.readlines()
                                for i in ligneRef : 
                                    page = urllib.parse.urljoin('http://www.europ-computer.com/produits/article_', '/article_%s' %i) # je définis mon url
                                    info = (urllib.request.urlopen(page).read()) # j'ouvre l'url et je stock le texte dans une variable
                                    info = info.decode("iso-8859-1") # on decode le texte
                                    fichierDesc.write(info) # et on écrit le texte dans le fichier
                                    fichierDesc.write(espace)
                                


                                Je ne joue pas avec mon objet, mais je passe par une variable "tampon" dirons nous, je viens pas directement écrire dans l'objet. En fait j'utilise mon objet (fichierDesc.write) au lieu de taper dedans avec un fichierDesc = ....

                                C'est ça ? :euh:

                                Je suis vraiment désolé de te donner tant de fil à retordre mais j'ai vraiment du mal ! :D Ceci dis, je te remercie pour ton aide et surtout pour ta patience !
                                • Partager sur Facebook
                                • Partager sur Twitter
                                Anonyme
                                  2 avril 2011 à 13:48:13

                                  C'est good, manque plus pour ton test, qu'une url te permettant de tester sans difficulté supplémentaire et des références correctes.

                                  la partie decode est à tester que si ton code source n'est pas lisible, au départ vaut mieux tester sans.

                                  Edit : N'oublies pas les +'\n' qui te permettent un retour à la ligne.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    2 avril 2011 à 13:56:19

                                    HAN !

                                    Avec une seule référence (qui contient le .html à la fin) ce code est fonctionnel:

                                    #-*- coding: utf-8 -*-
                                    import urllib.request, urllib.parse
                                    
                                    
                                    fichierRef = open('ref.txt', 'r')      
                                    fichierDesc = open('description', 'w') 
                                    espace = "---------------------------------------------------------------------"
                                    
                                    ligneRef = fichierRef.readlines()
                                    for i in ligneRef : 
                                        page = urllib.parse.urljoin('http://www.europ-computer.com/materiel-informatique-', '/materiel-informatique-%s' %i)
                                        info = (urllib.request.urlopen(page).read())
                                        info = info.decode("iso-8859-1")
                                        fichierDesc.write(info)
                                        fichierDesc.write(espace)
                                    


                                    J'ai juste eu le soucis de l'encodage que j'ai réglé avec la fonction decode().

                                    fred1599, je te remercie pour ton explication sur les objets, ça m'a permis de comprendre pourquoi certains autres de mes scripts étaient foireux !

                                    Une dernière question... ya moyen de se logguer sur un site en python ? ^^'

                                    EDIT: Et en effet, quand il y a une erreur 404 le script plante de partout, ce qui est logique ! Les ref sont différentes si on est logged ou pas, d'où les erreurs.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Anonyme
                                      2 avril 2011 à 14:02:06

                                      Citation

                                      ya moyen de se logguer sur un site en python ?



                                      Tu peux être plus explicite?

                                      Pour l'erreur 404, le problème est vite réglé, voir ici

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        2 avril 2011 à 14:11:43

                                        Citation : LeChat

                                        Une dernière question... ya moyen de se logguer sur un site en python ? ^^'


                                        Oui, simple requête POST pour faire comme si tu remplissais le formulaire de login + HTTPCookieProcessor pour retenir les cookies :

                                        opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor())
                                        opener.open(à utiliser comme la fonction urlopen)
                                        
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        Anonyme
                                          2 avril 2011 à 14:26:10

                                          Citation

                                          Oui, simple requête POST pour faire comme si tu remplissais le formulaire de login + HTTPCookieProcessor pour retenir les cookies :



                                          Pour faire ce genre de chose plus complexe le module urllib2 est plus adapté il me semble.

                                          Sinon pour en revenir à l'exercice une seule ligne fait tout le travail :lol:

                                          >>> import urllib.request
                                          >>> fic = urllib.request.urlretrieve('http://www.python.org', 'test.txt')
                                          
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            2 avril 2011 à 14:28:56

                                            Citation : fred1599

                                            Pour faire ce genre de chose plus complexe le module urllib2 est plus adapté il me semble.


                                            urllib.request (avec urllib.error) est le nouveau nom d'urllib2 dans Python 3.
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                            Anonyme

                                            [Algo] Récupérer le texte d'une URL

                                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                            • Editeur
                                            • Markdown