Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Exercice][Intermédiaire] Afficher un "VDM" aléatoire.

Pas trop dur, mais rigolo.

Sujet résolu
    26 juin 2012 à 8:39:23

    il y a quelque temps j'avais fait pareil pour le site pebkac.fr . il y a 3 fonctions pour des quotes aléatoires, le top 100 et le flop 100:
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    
    import html.parser
    import re
    import urllib.request as urllib
    
    QUOTE_OPENING = '<td class="pebkacContent">'
    QUOTE_ENDING  = '</td>'
    
    unescapeHtmlEnt = html.parser.HTMLParser().unescape
    
    def removePatternFromQuote(s, pattern):
        m = re.search(pattern, s)
        while m:
            s = s[:m.start()] + s[m.end():]
            m = re.search(pattern, s)
        return s
    
    def extractQuote(s):
        for p in ['<span.*?/span>', '<a.*?/a>', '<.*?>']:
            s = removePatternFromQuote(s, p)
        s = s.replace('\\r\\n', '\n')
        s = unescapeHtmlEnt(s)
        s = s[:len(s)-13] # removes " dd/mm/yy par" in the end
        return s
    
    def getQuotes(url):
        resp = urllib.urlopen(url)
        htmlResp = str(resp.read())
        m = re.findall(QUOTE_OPENING + '.*?' + QUOTE_ENDING, htmlResp)
        quotes = []
        if len(m):
            for q in m:
                quotes.append(extractQuote(q))
        return quotes
    
    def urlWithPage(url, page):
        if page == 1:
            return url
        return url + '&page=' + str(page)
    
    def randomQuotes():
        return getQuotes('http://www.pebkac.fr/pebkac-aleatoires.html')
    
    # page: 1 to 10, each page contains 10 quotes
    def top100Quotes(page = 1):
        return getQuotes(urlWithPage('http://www.pebkac.fr/index.php?p=top', page))
    
    # page: 1 to 10, each page contains 10 quotes
    def flop100Quotes(page = 1):
        return getQuotes(urlWithPage('http://www.pebkac.fr/index.php?p=flop', page))
    
    if __name__ == '__main__':
        for q in randomQuotes():
            print(q+'\n--\n')
    
    • Partager sur Facebook
    • Partager sur Twitter
      26 juin 2012 à 13:32:17

      One liner :

      import urllib.request
      from html.entities import name2codepoint
      from random import choice
      from string import Template
      import re
      
      
      print(choice([Template(re.sub(r'&(.*?);', r'${\1}', re.sub(r'(<.*?>)', '', re.search(r'(<a.*?VDM</a>)',m.group(1)).group(1)))).substitute({key:chr(entry) for key,entry in name2codepoint.items()}) for m in re.finditer('^.*(<div class=\"post article\".*)$', urllib.request.urlopen('http://www.viedemerde.fr/aleatoire').read().decode(), re.MULTILINE)]))
      


      Code d'origine :
      url = 'http://www.viedemerde.fr/aleatoire'
      
      def translate(html):
          d = {key:chr(entry) for key,entry in name2codepoint.items()}
          return Template(re.sub(r'&(.*?);', r'${\1}', html)).substitute(d)
      
      page = urllib.request.urlopen(url).read().decode()
      
      vdm_lst = []
      for m in re.finditer('^.*(<div class=\"post article\".*)$', page, re.MULTILINE):
          line = translate(re.sub(r'(<.*?>)', '', re.search(r'(<a.*?VDM</a>)',m.group(1)).group(1)))
          vdm_lst.append(line)
      
      print(choice(vdm_lst))
      


      Je n'utilise que des regex pour le parsing html, je sais que c'est assez crade, mais tel est mon choix pour l'exo.

      Sinon, le seul truc un peu intéressant, c'est la fonction translate (2e code) pour virer les codes html.

      • Partager sur Facebook
      • Partager sur Twitter
        28 juin 2012 à 19:28:12

        Salut !
        Tout d'abord merci beaucoup pour ce ptit exercice vraiment tip top.
        J'ai essayé de faire un truc à ma sauce qui reprenait le code source tout moche de la première page linké (http://www.viedemerde.fr/aleatoire)
        A priori ça marche, mais doit surement il y avoir des trucs maladroits. Je prends tous les avis. :)

        #coding: utf8
        
        import urllib
        from HTMLParser import HTMLParser
        import random
        
        class VDMParser(HTMLParser):
        	def __init__(self):
        		HTMLParser.__init__(self)
        		self.VDM = False
        		self.liste_VDM = []
        		self.fragments_VDM = []
        		
        	def handle_starttag(self, tag, attrs):
        		if attrs and attrs[0][1] == "post article":
        			self.VDM = True
        		if attrs and attrs[0][1] == "date":
        			self.VDM = False
        			VDM = self.reconstitution_VDM()
        			self.liste_VDM.append(VDM)
        			self.fragments_VDM = []
        
        	def handle_data(self, data):
        		if self.VDM:
        			self.fragments_VDM.append(data)
        	
        	def affichage_random_VDM(self):
        		print self.liste_VDM[random.randint(0, len(self.liste_VDM))]
        		
        	def reconstitution_VDM(self):
        		VDM = ""
        		for fragment in self.fragments_VDM:
        			VDM += fragment
        		return VDM
        
        parser = VDMParser()	
        fichier_VDM = urllib.urlopen("http://www.viedemerde.fr/aleatoire").read()
        parser.feed(fichier_VDM)
        parser.affichage_random_VDM()
        urllib.urlcleanup()
        



        De plus, si quelqu'un peut m'apporter quelques précisions sur certains points :
        - Imaginons qu'on veuille récupérer des données d'une page dont l'accès est restreint. Par exemple, les données ne sont accessibles qu'aux membres inscrits et connectés du site. Comment s'y prendre ?
        - Qu'est-ce que ça fait concrètement si on n'appelle pas urllib.urlcleanup() à la fin ? Ca laisse juste des données useless sur le cache ?

        Merci d'avance !
        • Partager sur Facebook
        • Partager sur Twitter
          23 juin 2013 à 23:18:24

          # -*- coding:Utf-8 -*-
          
          import urllib2
          from HTMLParser import HTMLParser
          
          
          def lire():
          	fichier = open("/home/user/Bureau/python/vdm.txt", "r+")
          	vdm = fichier.readlines()
          	taille = len(vdm)
          
          	try:
          		print "\n", vdm[taille-1]
          		size =  sum(len(mot) for mot in vdm) - len(vdm[taille-1])
          		fichier.truncate(size)
          
          	except:
          		data = urllib2.urlopen("http://www.viedemerde.fr/aleatoire")
          		htmlSource = data.read()
          		parser = MyHTMLParser()
          		parser.feed(htmlSource)
          		ecrire()
          		lire()
          	
          	fichier.close()
          
          def ecrire():
          	fichier = open("/home/user/Bureau/python/vdm.txt", "a+")
          
          	i = 0
          	while i < len(vdm):
          		if "VDM" in vdm[i]: vdm[i] += '\n'
          		fichier.write(vdm[i])
          		i+=1
          
          	fichier.close()
          
          
          class MyHTMLParser(HTMLParser):
          	flag = False
          
          	def handle_starttag(self, tag, attrs):
          		if tag == "a":
          			for name, value in attrs:
          				if name == "class" and value == "fmllink":
          					self.flag = True
          
          	def handle_endtag(self, tag):
          		if tag == "a":
          			self.flag = False
          
          	def handle_data(self, data):
          		if self.flag and data !=".":
          			vdm.append(data)
          
          
          vdm = []
          lire()

          Bonsoir, voilà ma version :D

          Il faut savoir que sur la page random de VDM on récupère 15 anecdotes, mais j'en affiche qu'une seule. Pour éviter le gâchis des autres vdm, j'ai stocké ça dans un fichier texte. Ainsi, à chaque exécution du script, une VDM est retirée du fichier (sans réécriture), jusqu'à qu'il y en ait plus.

          Et si il y a en a plus, il va en récupérer 15 autres etc etc...

          Voilà :)

          -
          Edité par Hyperyon 23 juin 2013 à 23:19:56

          • Partager sur Facebook
          • Partager sur Twitter

          [Exercice][Intermédiaire] Afficher un "VDM" aléatoire.

          × 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