D'utiliser 2 ou 3 modules de la bibliothèque standard de Python ;
Vous connaissez tous, je suppose, le site VieDeMerde ?
Je vous propose d'écrire un petit script en Python qui affiche un "VDM du jour" au hasard.
Démonstration :
15:13 arnaud@laptop % python3 vdmdujour.py
Aujourd'hui, et depuis 1 an, j'ai des vues sur une amie du théâtre. Célibataire invétéré aux 25 râteaux, je lui demande de sortir avec moi. Elle refuse. 26. Le soir, je reçois un message de sa part me disant qu'elle m'aime. Bizarre, mais bon. Plus tard, je vais la voir. C'était sa cousine qui s'amusait. 27. VDM
15:13 arnaud@laptop % python3 vdmdujour.py
Aujourd'hui, J'ai parlé sans y penser, du groupe de death metal Dying Fetus à un collègue dont la femme venait de faire une fausse couche la semaine précédente... VDM
Pour cela, vous devrez :
Vous connecter sur le site, par exemple à l'url : http://www.viedemerde.fr/aleatoire, ou bien, (beaucoup plus facile !), sur le fil de syndication : http://feeds.feedburner.com/viedemerde?format=html, et récupérer une page html brute, mais remplie de VDM.
Le module urllib de Python peut vous aider à ce sujet (utilisateurs de Python3, attention à la note en haut de la page ).
"Parser" la page que vous avez récupérée pour en extraire les textes des VDM. Pour cela, vous pouvez utiliser le module HTMLParser, mais cela vous demandera de dériver l'interface qui y est décrite. L'utilisation d'expressions régulières est aussi à prévoir...
Afficher votre VDM du jour (par exemple, choisie aléatoirement parmi toutes les VDM que vous aurez récupérées).
Marche à suivre alternative, plus simple et ne nécessitant pas de programmation orientée objet :
Pour avoir pas mal utilisé le module HTMLParser, je le déconseille. Mon script plantait pas mal de fois pour des balises mal fermées, oubliées, etc. dans le code source de la page importée.
Je viens de travailler avec le module xml et plus précisément la classe ElementTree (avec Python 3.1) et je dois dire que c'est un vrai bonheur. S'il est possible d'utiliser le flux Atom comme le suggère spider-mario (après tout, le plus important est le but et non les moyens employés), je vous conseille vivement de parser du xml.
Btw, merci NoHaR pour ce sujet intéressant et qui demande de mettre la main à la pâte.
Ah oui, bonne idée.
Le but est d'obtenir un VDM aléatoire à chaque exécution du script. La solution que j'ai proposée pour guider ceux qui ne sauraient pas comment faire n'est qu'indicative : toute proposition permettant d'obtenir le même résultat plus simplement en n'utilisant de préférence que l'API standard Python est la bienvenue.
Bon, le sujet m'a vraiment plu. J'ai donc fais un petit truc rapidement (très rapidement) qui fonctionne bien. Je n'ai pas regardé s'il était possible d'optimiser et je ne le ferai sans doute pas. Je voulais juste quelque chose qui fonctionne et de toute manière, le temps me manque.
from xml.etree import ElementTree
from urllib.request import urlopen
from random import randrange
flux_vdm = ElementTree.iterparse(urlopen('http://feeds.feedburner.com/viedemerde'))
liste_vdm = []
for position, attribut in flux_vdm:
if 'title' in attribut.tag: liste_vdm.append(attribut.text)
if 'content' in attribut.tag: liste_vdm.append(attribut.text.split('VDM')[0])
hasard = randrange(0, len(liste_vdm))
if hasard%2 == 0: print(liste_vdm[hasard], liste_vdm[hasard+1]+'VDM.', sep='\n')
else: print(liste_vdm[hasard-1], liste_vdm[hasard]+'VDM.', sep='\n')
Par contre, je n'ai rien commenté du tout. Je poste ici en coup de vent et reviendrai plus tard pour clarifier tout cela .
Clairoune53 a une VDM
Aujourd'hui, je travaille dans un camping en tant que saisonnière et je reçois un appel pour une réservation pour le mois de septembre. L'homme m'a engueulée car je n'étais pas fichue de savoir quel temps il ferait le week-end où il avait prévu de venir. Dans deux mois donc. VDM.
Bien joué.
En entendant parler d'une solution qui utiliserait ElementTree, j'ai essayé moi-même d'obtenir le même résultat par ce moyen, c'est vrai que c'est une solution beaucoup plus simple.
Voilà ce que je viens de faire en 2 minutes (je ne pas récupère pas les titres..., et c'est commenté juste pour prendre des airs de "correction") :
import re
import random
import xml.etree.ElementTree as ET
from urllib.request import urlopen
# Expression régulière : une VDM commence par 'Aujourd'hui,'
# et se termine par 'VDM'
VDM_TEMPLATE = "(?P<value>Aujourd'hui,.* VDM)"
# On ouvre le flux XML
feed = urlopen("http://feeds.feedburner.com/viedemerde?format=xml")
# On récupère le flux XML sous forme d'une liste d'objets Element
flux_xml = [item for _, item in ET.iterparse(feed)]
# On isole dans une liste toutes les entrées "VDM" qui se trouvent entre des
# balises <content>
liste_vdm = [elt.text for elt in flux_xml if 'content' in elt.tag]
# On en choisit une au hasard
vdm = random.choice(liste_vdm)
# On l'affiche, en n'isolant que le texte de la VDM en question grâce à
# l'expression régulière.
print(re.search(VDM_TEMPLATE, vdm).groupdict()['value'])
EDIT : J'ai corrigé la manière dont j'ouvre le flux XML. Je m'étais un peu compliqué la vie.
Hum. Quand on fait vite, on fait mal (du moins, dans mon cas). :/
from xml.etree import ElementTree
from urllib.request import urlopen
from random import choice
flux_vdm = ElementTree.iterparse(urlopen('http://feeds.feedburner.com/viedemerde'))
liste_vdm = [element[1].text.split('VDM')[0]+'VDM.' for element in flux_vdm if 'content' in element[1].tag]
print(choice(liste_vdm))
P.S : merci pour ta contribution NoHaR, je la trouve vraiment intéressante avec l'utilisation d'expressions régulières. :-)
P.S² : et le pire, c'est que cette version a été beaucoup plus facile à concevoir et à faire fonctionner (2 minutes contre 10 bonnes minutes pour l'autre). Et en plus, elle bouffe moins de ressources \o/.
Si tu veux compresser, pour le fun, tu peux la faire en une ligne (sans compter les imports) aussi:
import re, random, xml.etree.ElementTree as ET, urllib.request
print(re.search("(?P<value>Aujourd'hui,.* VDM)", random.choice([elt.text for _, elt in ET.iterparse(urllib.request.urlopen("http://feeds.feedburner.com/viedemerde")) if 'content' in elt.tag])).groupdict()['value'])
EDIT: C'est vrai qu'en groupant les imports, on arrive à 2 lignes. Merci pour la remarque EMC1.
Vous connecter sur le site, par exemple à l'url : http://www.viedemerde.fr/aleatoire et récupérer une page html brute, mais remplie de VDM.
Le module urllib de Python peut vous aider à ce sujet (utilisateurs de Python3, attention à la note en haut de la page ).
"Parser" la page que vous avez récupérée pour en extraire les textes des VDM. Pour cela, vous pouvez utiliser le module HTMLParser, mais cela vous demandera de dériver l'interface qui y est décrite. L'utilisation d'expressions régulières est aussi à prévoir...
Afficher votre VDM du jour (par exemple, choisie aléatoirement parmi toutes les VDM que vous aurez récupérées).
Marche à suivre alternative, plus simple et ne nécessitant pas de programmation orientée objet :
Parcourir le flux xml au moyen du module ElementTree de python
Choisir une VDM au hasard, et l'afficher dans la console.
Bon courage !
+15
Cet exercice n'est pas à ma portée, cependant tu pousses les débutants à le faire en y incorporant des indices que j'ai cités plus haut. Pourquoi tous les exercices ne sont ils pas comme ça ?
Je vais essayer de faire l'exercice malgrès sa complexité. Enfin je dis "complexe" car je n'ai pas encore fais de recherches
NoHaR > Nân, je suis (en temps normal) allergique à ce genre de choses. Je ne cherchais pas tellement à compresser mais plutôt à être concis et optimiser. Enfin, mon deuxième code est forcément plus petit que le premier puisqu'il ne gère que la citation alors que l'autre prenait le titre en plus. Parce dans ce dernier cas, j'aurai probablement préféré mon premier code à un code utilisant les listes compréhension, moins lisible à mon goût (mais peut-être plus puissant).
Edit : parce que le fun amuse ( ):
from xml.etree import ElementTree
from urllib.request import urlopen
from random import choice
print(choice([contenu[1].text.split('VDM')[0]+'VDM.' for contenu in ElementTree.iterparse(urlopen('http://feeds.feedburner.com/viedemerde')) if 'content' in contenu[1].tag]))
En fait, je ne souhaite pas importer les modules entièrement. Juste la partie qui m'est utile. Et je n'ai pas réussi à caser toutes mes importations sur une ligne. J'ai essayé plusieurs combinaisons mais toujours fausses.
EDIT : bah, dans ce cas, je te bats à plate couture sur les allocations de mémoire NoHaR. Importer un module entièrement pour n'en utiliser qu'une infime partie est forcément plus gourmand en ressource. Haha.
Ha oui, c'est vrai que c'tait pour le fun. :-) Bah, on est tous les deux à deux lignes alors, avec pourtant deux méthodes différentes. Je trouve cela intéressant et amusant.
C'est vrai qu'on a oublié une solution utilisant HTMLParser. Enfin, j'ai jeté un coup d'œil au code source du fil de syndication et ça ne devrait pas poser de soucis, il est bien organisé. A partir de là, je coderai juste une petite classe de parsage, dérivant de HTMLParser et dont la fonction sera de rajouter dans une liste chaque citation après la balise <div class="itemcontent" name="decodeable">.
EDIT : je trouve ton code un peu long et peu compréhensible, en vérité. Enfin, quand on voit le code source de la page que tu as pris... (c'est pour ça que si je code un truc, c'est en me basant sur le flux Atom).
Tu as raison, il est plutôt sale. Je n'avais pas pensé à jeter un oeil au flux Atom avant de faire ce code, donc j'ai parsé la page web brute...
En parsant le flux Atom, le code devrait contenir moins de merdouilles (des "div" imbriqués, entre autre, qui m'obligent à créer une sorte de pile pour ignorer ceux qui ne conviennent pas), et être plus propre.
Je verrai ça demain.
Voici le résultat, beaucoup plus clair (et commenté).
#! /usr/bin/env python3
from html.parser import HTMLParser
class VDMParser(HTMLParser):
def __init__(self):
"""
Construction du VDMParser.
Celui-ci contient simplement un 'flag' indiquant si l'on est en train
de lire un VDM ou non, ainsi qu'une liste des vdm déjà récupérées.
"""
HTMLParser.__init__(self)
self.inpost = False # est-on en train de lire un VDM ?
self.vdm = [] # liste des vdm que l'on a récupérées
def handle_starttag(self, tag, attrs):
"""
Méthode appelée chaque fois qu'une balise ouvrante est détectée.
Ici : elle détecte simplement l'ouverture des balises
<div class="itemcontent">
qui contiennent les textes des VDM.
"""
attrs = dict(attrs)
if tag.lower() == 'div':
if 'class' in attrs and attrs['class'] == 'itemcontent':
self.inpost = True
def handle_endtag(self, tag):
"""
Méthode appelée chaque fois qu'une balise fermante est détectée.
Ici : elle détecte simplement la fermeture des balises </div>
"""
if tag.lower() == 'div':
self.inpost = False
def handle_data(self, data):
"""
Méthode appelée à chaque ligne pour des "données" contenues entre des
balises.
Ici : si l'on est en train de lire un vdm, on l'ajoute à notre liste
"""
if self.inpost:
self.vdm.append(data)
def main():
"""
Fonction principale qui récupère et affiche une VDM au hasard.
"""
from urllib.request import urlretrieve, urlcleanup
from random import choice
# On récupère le flux dans un fichier temporaire
fichier, _ = urlretrieve("http://feeds.feedburner.com/viedemerde?format=html")
# On ouvre ce fichier et on en lit le contenu
string = open(fichier).read()
# On donne le contenu du fichier à traiter au VDMParser
parser = VDMParser()
parser.feed(string)
# Le parser a terminé son travail, on récupère un VDM au hasard et on
# l'affiche
print(choice(parser.vdm))
# On n'oublie pas d'effacer le fichier temporaire
urlcleanup()
if __name__ == '__main__':
main()
Heuh bon vous allez trouver ma question idiote :
Quel est l'interet de faire un programme en python pour généré une VDM aléatoirement ?
Ce ne serait pas plus logique de faire cela dans un langage Web genre PHP ? Bon je sais qu'aprés il y a des fous furieux et que, parait il, on peut foutre du python en ligne...
enfin c'est ce que j'ai cru comprendre une fois
Ce ne serait pas plus logique de faire cela dans un langage Web genre PHP ? Bon je sais qu'aprés il y a des fous furieux et que, parait il, on peut foutre du python en ligne...
Bon alors maintenant je suis sûr la question précédente est idiote. Ici on est dans le forum python, on s'entraîne sur ce langage et non sur un autre quelquesoit l'exercice.
Je trouve que tu fais un peu ton trolleur, non?
Va à l'adresse ci-dessous, tu verras ce qu'on peut faire avec un framework web type django
Oui bien sur que vous vous entrainez sur du python puisqu'on est dans la catégorie python. Mais je trouve que c'est étrange...
Comme si un charcutier faisait de la pâtisserie quoi !
(Et merci pour le lien mais je ne parle pas anglais ! Mais apparemment django permet d'utiliser python pour le web ?)
Sans rentrer dans le troll, je vais y aller de ma réponse (puisque j'ai eu l'idée de cet exo).
D'abord, je n'aime pas trop l'expression "langage web". Elle porte à croire que certains langages de programmation sont créés spécifiquement pour le web (qui a dit PHP ?), ce qui est plus ou moins faux : certains frameworks le sont (GWT, Pyjamas, Django...) mais le langage reste un langage.
Ensuite, comme ça a été dit, Python est aussi utilisé pour le développement web (Django, toosa...).
Après, la clé de cet exercice n'est pas tellement la communication sur le réseau (qui se fait ici à haut niveau), mais plus le parsing de la page que l'on récupère : c'est l'une des utilisations de Python les plus banales.
Enfin, ce qui fait que cet exercice est tout à fait adapté à Python, c'est que l'on peut le résoudre en n'utilisant que des fonctions de la bibliothèque standard (c'est d'ailleurs le but de l'exo, pousser le débutant à aller lire la doc de l'API standard de Python pour résoudre ce petit problème).
Ha ok !
J'avais posé ma petite question parceque sur le coup , ce genre d'application me paraissait utile sur du web (et je ne connaissais pas django...) Donc genre on se proméne sur un site et sur la page d'accueil ya une VDM qui apparait aléatoirement...
Enfin bref là j'ai compris l'utilité du truc !
Merci !
Le débat est désormais clos
ou alors, ça peut aussi servir sur une desklet de geek (inutile donc indispensable) qui affiche une VDM différente sur le bureau toutes les 5 minutes, ou comme message d'accueil lorsque l'on vient de se logger en console sous Linux.
Ce genre de pratique (parsing XML) peut aussi donner lieu à des trucs marrants comme récupérer les commentaires de log SVN (svn log --xml) et les dépioter pour travailler dessus, parser un fichier de sortie ou de configuration d'un autre programmme, etc.
#!usr/bin/env/python
# -*- coding: Latin-1 -*-
import urllib2
import re
import random
######################################################
# Script affichant une VDM #
# aléatoire à partir de #
# l'adresse: #
# http://feeds.feedburner.com/viedemerde?format=html #
######################################################
# On ouvre le fichier avec la librairie urllib
# On stocke le contenu du fichier dans la variable page_web
page_web=urllib2.urlopen("http://feeds.feedburner.com/viedemerde?format=html")
# Chaque ligne du fichier est stocké comme étant un élément de la liste lignes_page_web
lignes_page_web=page_web.readlines()
# On n'oublie pas de fermer le fichier!!
page_web.close()
# On créer une liste vide qui va contenir l'ensemble des vdm récupérées
liste_vdm=[]
# On stocke une expression régulière dans une variable.
expression="^<div\sclass"
# On va rechercher cette expression régulière dans notre fichier
# On parcourt notre liste contenant toutes les lignes de notre fichier web
for i in lignes_page_web:
# On recherche l'expression régulière
if re.search(expression,i):
# On sépare notre chaine de caractère (notre ligne) avec le caractère ">"
i=i.split(">")
# On stocke le deuxième élément de la liste dans une variable
j=i[1]
# On effectue une nouvelle séparation de notre chaîne de carcatère
j=j.split("VDM")
# On ajoute la chaine de caractère à notre liste vide
liste_vdm.append(j[0])
# On effectue un tirage aléatoire entre 0 et la longueur de notre liste -1
vdm_hasard=random.randint(0,len(liste_vdm)-1)
# On affiche la vdm
print liste_vdm[vdm_hasard]
J'ai vu que certains avaient codés des classes etc, si c'est un exercice de niveau intermédiaire c'est peut être un poile compliqué de faire ça comme ça nan ?
Sympa cet exo. Je suis même permis de le faire pour DTC à partir de la solution:
#-*- coding:Latin-1 -*
import re
import random
import xml.etree.ElementTree as ET
from urllib import urlopen
# On ouvre le flux XML
feed = urlopen("http://feeds.feedburner.com/bashfr-quotes?format=xml")
# On récupère le flux XML sous forme d'une liste d'objets Element
flux_xml = [item for _, item in ET.iterparse(feed)]
# On isole dans une liste toutes les entrées DTC
liste_dtc = [elt.text for elt in flux_xml if 'description' in elt.tag]
# On en choisit une au hasard et on sépare la quote du reste de l'HTML
dtc = random.choice(liste_dtc)
dtc = dtc.split("<a ")[0]#Pour obtenir uniquement la quote
#On remplace quelques caractères spéciaux
dtc = dtc.replace("<br />", "", dtc.count("<br />"))
dtc = dtc.replace(">", ">",dtc.count(">"))
dtc = dtc.replace("<", "<", dtc.count("<"))
dtc = dtc.replace(""", '"', dtc.count("""))
print dtc
[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.