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 :

HTMLParser - Problème mémoire?


Sujet :

Python

  1. #1
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 665
    Par défaut HTMLParser - Problème mémoire?
    Bonjour à tous!

    Voici le topo:

    Je cherche à récupérer de façon automatique et périodique quelques informations boursières issues de yahoo finances. Je compte pour cela utiliser uniquement les modules pré-installés avec Python. J'ai fait une première tentative plutôt concluante que voici:

    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
    import urllib2
    import HTMLParser
     
     
    class Parser(HTMLParser.HTMLParser):
    	"""
                    Parser test
            """
    	def __init__(self):
    		HTMLParser.HTMLParser.__init__(self)
    		self.FindOuverture = False
    		self.OuvertureValue = 0.0      
     
    	def handle_data(self,data):
    		if self.FindOuverture:
    			self.OuvertureValue = float(data.replace(',','.'))
    			self.FindOuverture = False
    		if data == 'Ouverture:':
    			self.FindOuverture = True
     
    	def DisplayData(self):
    		print ("Ouverture: " + str(self.OuvertureValue))
     
     
    if __name__ == "__main__":
     
    	parser = Parser()
    	webPage = urllib2.urlopen("http://fr.finance.yahoo.com/q?s=EN.PA&ql=0")
    	html = webPage.read()
    	parser.feed(html)
    	parser.DisplayData()
    	# Section qui doit merdé à mon avis
    	parser.reset()
    	parser.close()
    Ici, je récupère la valeur boursière à l'ouverture de l'entreprise Boeing.

    Mon problème c'est que sur Win7 avec Python 2.7 lorsque je lance le script une première fois tout roule mais lors d'une nouvelle tentative il affiche la valeur par défaut (0.0). J'ai remarqué qu'il me fallait patienter quelques instants (plusieurs dizaines de secondes) avant de pouvoir récupérer la valeur succès, et ce malgré le reset (dont je ne vois finalement pas trop l'utilité mais que j'ai rajouté "aucasou") et le close.

    Mais sur ma machine perso (Ubuntu 12.04 et python 2.7), ça marche parfaitement, même en lançant le script à la suite.

    Des idées?

    Merci,

    Ju

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 778
    Par défaut
    Salut,

    Amusez vous à chronométrer la durée de webPage.read() et celle de parser.feed(html): webPage.read() devrait être de l'ordre de 10ms et 10000 à 100000 plus long que que parser.feed(html)
    Si Ubuntu était 10 fois plus rapide que Windows (c'est une hypothèse), parser.feed(html) prendrait moins de 0,1% de ces 10ms.
    Si vous constatez des "différences", il faut plutôt s'inquiéter côté topologie réseau, débit de l'accès internet (qui peut partagé avec d'autres).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 665
    Par défaut
    Salut wiztricks,

    Je viens de comparer le temps pris par webPage.read() et parser.feed(html). Résultat:
    • webPage.read() --> 0.001s
    • parser.feed(html) --> 0.810s (fluctuant)

    Test effectué avec le module profile.

    Je pense que tu as mis le doigt sur le problème en évoquant le réseau. Le PC sous windows est mon poste fixe du bureau. Le réseau internet est naturellement partagé, protégé, filtré... Et ce avec de très nombreuses personnes (plusieurs milliers).

    Si le problème vient de là je ne pourrais pas le contourner. Est-ce que tu aurais une piste pour valider ou invalider l'hypothèse?

    Ju

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 778
    Par défaut
    Ma théorie "fonctionnerait", si vous aviez posté:
    • webPage.read() --> 0.810s (fluctuant)
    • parser.feed(html) --> 0.001s

    Si vous postez des résultats "inverses":
    • webPage.read() --> 0.001s
    • parser.feed(html) --> 0.810s (fluctuant)

    C'est que vous vivez dans un sorte d'univers parallèle dans lequel les lois de la physique de mon univers ne s'appliquent pas - c'est pas grave, juste que je ne pourrais pas "aider".
    Confirmez les données.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 665
    Par défaut
    Voilà ce que c'est que d'être fan de Sliders...

    Je confirme les résultats (partiels) de Profile:

    0.023 profile:0(webPage.read(); print)
    0.950 profile:0(parser.feed(html); print)[/
    Pour quelle raison la méthode read() devrait elle être bien plus longue que l'utilisation du parser?

    Ju

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 778
    Par défaut
    Dans mon univers, çà donne (mesuré avec time.clock)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    C:\py_works\bidon>py -2.7 blah6.py
    page.read, elapsed: 0.226
    Ouverture: 22.5
    parser, elapsed: 0.057
    Le temps d'accès réseau est 20X plus grand que l'analyse du contenu de la page retournée - parce que mon PC bosse à autre chose.

    Pour quelle raison la méthode read() devrait elle être bien plus longue que l'utilisation du parser?
    Parce que les accès réseau sont de l'ordre de la milliseconde alors que les accès mémoire sont de l'ordre de la nanoseconde.

    Cà va un million de fois plus vite mais comme on exécutes instructions machines pour bouger les données d'une case mémoire à l'autre et que Python demande beaucoup d'instructions machines, çà n'ira pas aussi "vite".

    Par contre, normal que lire une page réseau prenne un temps variable - çà attend que le serveur Yahoo réponde. Regardez ce qu'il y a dedans (parser) dépend du nombre d'octets de la page et devrait être +/- constant, vous lisez les mêmes infos.

    Si çà varie, c'est que d'autres activités "système" empruntent le CPU pendant l'exécution de votre code. Avec moins de ressource CPU disponible, le même boulot, prendra plus de temps.

    => Si vous savez "a peu près" ce qu'il se passe sur votre machine, côté accès réseau, il y a un mode qui bouge et des bande passantes (embouteillages) qui évoluent dans le temps.
    Ce sera plus long et la variabilité pourra être beaucoup plus grande.

    Voilà comment çà se passe sur la planète Terre que je connais.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 665
    Par défaut
    Voilà qui est très intéressant. Je viens de renouveller l'expérience mais cette fois en utilisant moi aussi time.clock(). Cette fois les résultats sont en accord avec les votre:

    webPage.read() elapsed: 0.124
    parser.feed(html) elapsed: 0.024
    Finalement il semblerait que je n'ai pas glissé dans un autre univers!

    Je n'ai jusqu'à présent utilisé le module profile qu'une seule fois, et seulement par curiosité (je ne suis pas assez bon pour me soucier d'optimisation, si ça marche c'est déjà bien!). Je vais me documenter sur le sujet dès que j'aurais un moment de libre. Cette différence est vraiment étonnante.

    Revenons au problème initial si vous voulez bien. Admettons que je lance deux fois à la suite mon programme. La première fois, j'obtiens le résultat attendu, la seconde la valeur par défaut (0.0). Si c'est le cas, c'est que mes conditions ne sont pas vérifées et par conséquent que les données cherchées ne sont par relevées.

    Si je demande à afficher data au fur et à mesure que handle_data est appelée, je n'obtiens qu'un fragment de la page. Plus exactement le bordereau (headers, connexions, etc...). Pas le contenu à proprement parlé.

    Cela signifirais que la page n'est pas réellement chargée? J'avoue ne pas m'y connaître en réseau. Je devrais certainement me pencher un peu plus sur le sujet.

    Ju

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 778
    Par défaut
    Citation Envoyé par Julien N Voir le message
    Voilà qui est très intéressant. Je viens de renouveller l'expérience mais cette fois en utilisant moi aussi time.clock().
    Utilisez plutôt time.time, si vous faites des tests multi-plateforme.
    Lisez la doc pour comprendre.

    Cela signifirais que la page n'est pas réellement chargée? J'avoue ne pas m'y connaître en réseau.
    A la base, le protocole réseau ne sait échanger que des flots de bytes (stream). Au dessus, on met un protocole (HTTP).
    Ca va découper ces bytes en "messages" i.e. tant qu'on n'a pas "fin du message" ou reçu le "nombre d'octets attendus", çà attend jusqu'à "timeout'.
    => vous recevez correctement la "page".

    La question serait plutôt: qu'est ce qui garantit de toujours trouver "'Ouverture:"?

    L'autre sujet pourrait être: pensez vous qu'un site comme Yahoo accepte de répondre à un "robot" alien qui ne se conforme pas au protocole des robots en faisant des requêtes un peu trop vite a son goût depuis une adresse internet inconnue quelque part en France?
    Il s'agit d'éviter que les utilisateurs "normaux" se plaignent, les gamins de Chine ou d'ailleurs fassent parler d'eux en vandalisant un site, des coups de clics sur les pubs qui ne se font pas, des revenus baissent, une action en chute libre et le CEO est viré.
    Vu les enjeux, des "contre-mesures" sont en place.

    Mais ce n'est peut être pas encore le problème.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 665
    Par défaut
    Ok pour time. Je viens de lire les principales différences.

    Il y a une chose à laquelle j'aurais dû penser tout de suite: essayer mon code sur un autre site...

    http://www.google.com/finance?q=boei...fCcBsGNwAP2rAE

    Avec cette page, je peux lancer à la suite plusieurs requêtes sans rencontrer de soucis. Le problème viendrait donc de yahoo finance.

    Merci beaucoup pour tous ces éclaircissenent. Je vais maintenant m'attaquer à la suite.

    De toute façon mon objectif n'était que de faire une requête par heure afin d'enregister des données historiques, pas de récupérer en temps légèrement différé des infos. Mais bon, comme je suis curieux je me suis tout de même penché sur la question.

    Encore merci!

    Je passe en résolu?

  10. #10
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 778
    Par défaut
    Citation Envoyé par Julien N Voir le message
    De toute façon mon objectif n'était que de faire une requête par heure afin d'enregister des données historiques, pas de récupérer en temps légèrement différé des infos. Mais bon, comme je suis curieux je me suis tout de même penché sur la question.
    De nos jours la plupart des (gros) sites offrent des interfaces "programmatiques".
    Elles permettent de récupérer les informations directement et dans un format plus adapté.
    Faire une requête en se faisant passer pour un navigateur aboutit à rechercher une information simple dans un gros tas avec des heuristiques peu fiable. Si Yahoo change la présentation de ses pages, allez vous détecter le changement ou vous poser des questions des semaines après en regardant un tableau?

    Ces interfaces devraient permettre l'accès aux données historiques.
    Pas la peine de les stocker chez vous: une requête pour récupérer les données des X dernières semaines, mois, années, ... et les présenter comme vous voulez.

    Recherchez sur google "Python Yahoo Finance".

    Encore merci!

    Je passe en résolu?
    C'est une convention qui mérite d'être respectée.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 665
    Par défaut
    Si Yahoo change la présentation de ses pages, allez vous détecter le changement ou vous poser des questions des semaines après en regardant un tableau?
    C'est juste. L'objectif n'est pas bien entendu de faire quelque chose d'original, puissant et propre. J'en serais bien incapable. La récupération de données boursières ne sert ici que de prétexte. J'avais aussi dans l'idée de produire un module proche de ce que proposent de nombreux scripts lua.

    De plus, si à chaque fois que l'on a une envie ou le besoin (même ponctuel) de quelque outil que que ce soit on devait systématiquement rechercher la solution optimale et déjà rédigée par quelqu'un d'autre, ce serait bien triste... La plupart du temps je n'utilise même pas ce que je cosntruis. Le plaisir réside dans la recherche, le développement et bien entendu lorsqu'enfin ça marche!

    Pour revenir au problème boursier ici évoqué, Google (entre autres) fourni des données historiques très complètes sur 1 mois, 6 mois, 1 an, 5 ans, +10ans.. Et le tout exportable en .csv. Là on touche à l'utile.

    Ciao

    Ju

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

Discussions similaires

  1. Problème mémoire, c'est grave là :/
    Par gamerome dans le forum C++
    Réponses: 6
    Dernier message: 12/08/2005, 12h29
  2. [CR9] [VB.NET] problème mémoire
    Par prophetky dans le forum SDK
    Réponses: 1
    Dernier message: 26/05/2005, 08h36
  3. Problème mémoire
    Par charliejo dans le forum MFC
    Réponses: 8
    Dernier message: 13/04/2005, 13h45
  4. Problémes mémoire avec le bde sur des bases paradox
    Par Keke des Iles dans le forum Bases de données
    Réponses: 2
    Dernier message: 27/05/2004, 16h55
  5. Problème mémoire avec une dll par chargement dynamique
    Par widze19 dans le forum C++Builder
    Réponses: 6
    Dernier message: 15/12/2003, 13h20

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