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 :

parser pour le plaisir [Python 3.X]


Sujet :

Python

  1. #1
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut parser pour le plaisir
    Bonsoir,
    Toujours pour le plaisir, je souhaite tenter de parser des fichiers.
    Le programme que j'employais jusqu'à présent ne fonctionne plus suite à une refonte du site "marmiton" (refonte qui a lieu régulièrement tous les 6 mois ou tous les ans).
    Derrière, j'utilise LaTeX qui me crée un pdf de la recette.
    Je vous propose le programme suivant qui fonctionne mais qui me semble peu efficace (basé sur ce que je faisais jusqu'à présent).
    J'imagine qu'il y a beaucoup mieux via les regex (je suis allergique) ou HTMLParser.
    Si vous avez des idées, je suis preneur...
    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
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    #url = "http://www.marmiton.org/recettes/recette_flan-aux-oeufs-maison_86967.aspx"
    url = "http://www.marmiton.org/recettes/recette_cookies-maison_86989.aspx"
     
    import urllib
    from bs4 import BeautifulSoup
    import json
     
    f = urllib.request.urlopen(url)
    src = f.read()
    g = open("recette_0.txt","wb")
    g.write(src)
    g.close()
     
    soup = BeautifulSoup(src,"lxml")
    ensemble = soup.find( "script", type = "application/ld+json" )
    recette = (str(ensemble))[58:-22]
    print(recette)
     
    dic_recette = json.loads(recette)
    print(type(recette))
    print(dic_recette)
    print(type(dic_recette))
    print(dic_recette["name"])
    print(dic_recette["recipeYield"])
    Bien entendu, si qqn souhaite le programme une fois fini, je le livrerai.

  2. #2
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 305
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 305
    Par défaut
    Salut,

    Que pense-tu de ceci:
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    # -*- coding: utf-8 -*-
     
    import urllib.request
    import json
    from html.parser import HTMLParser
     
    def get_page(url):
        try:
            content = urllib.request.urlopen(url).read()
            return str(content.decode('utf-8', 'replace'))
        except Exception as why:
            print('urllib2 error: %s, %s' % (url, why))
            return False
     
    def get_recipe(link):
        page = get_page(link)
        if page:
            parser = Parser()
            parser.feed(page)
            if parser.recipe:
                miam(parser.recipe)
     
    def miam(jsn):
        recette = json.loads(jsn)
        print("\n * %s\n" % recette["name"])
        ing = ', '.join(recette["recipeIngredient"])
        print("Dépends: %s\n" % ing) 
        print(recette["recipeInstructions"])
     
    class Parser(HTMLParser):
        def __init__(self):
            super().__init__()
            self.recipe = False
            self.injson = False
     
        def handle_starttag(self, tag, attrs):
            if tag == "script":
                # attrs doit être de la forme "[('type', 'application/ld+json')]"
                if attrs and 'application/ld+json' in attrs[0]:
                    self.injson = True
     
        def handle_data(self, data):
            if self.injson:
                self.clean_data(data)
                self.injson = False
     
        def clean_data(self, txt):
            begin = '{"@context"'
            end = ',"aggregateRating"'
            r = begin + txt.split(begin)[1]
            self.recipe = r.split(end)[0] + "}"
     
    if __name__ == "__main__":
        get_recipe("http://www.marmiton.org/recettes/recette_cookies-maison_86989.aspx")
    Je pense que ce doit être nettement plus rapide que avec BeautifulSoup.

    Bon appétit.

  3. #3
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut
    Merci VinsS,
    En effet, c'est beaucoup plus rapide.
    Je vais tenter de comprendre et de m'approprier tout cela.

  4. #4
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut
    Merci encore, je suis parvenu à faire ce que je voulais.
    La partie suivante me pose encore problème mais j'y travaille :
    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
    class Parser(HTMLParser):
        def __init__(self):
            super().__init__()
            self.recipe = False
            self.injson = False
     
        def handle_starttag(self, tag, attrs):
            if tag == "script":
                # attrs doit être de la forme "[('type', 'application/ld+json')]"
                if attrs and 'application/ld+json' in attrs[0]:
                    self.injson = True
     
        def handle_data(self, data):
            if self.injson:
                self.clean_data(data)
                self.injson = False
     
        def clean_data(self, txt):
            begin = '{"@context"'
            end = ',"aggregateRating"'
            r = begin + txt.split(begin)[1]
            self.recipe = r.split(end)[0] + "}"

  5. #5
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut
    Bonsoir,
    J'ai maintenant 2 méthodes
    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
    import urllib.request
    import bs4 as BS
    html = urllib.request.urlopen("http://www.marmiton.org/recettes/recette_flan-aux-oeufs-maison_86967.aspx").read()
    html = str(html.decode('utf-8', 'replace'))
    soup = BS.BeautifulSoup(html,"html")
    import re
     
    texte = soup.find_all("script",type={"application/ld+json"})
    print("texte : ", texte)
    print()
    recherche = re.compile("(?<=\{)(.*?)(?=\})", re.DOTALL)
    match = recherche.search(str(texte))
    print(match.group(1))
    print()
    dico="{"+match.group(1)+"}}"
    print("dico : ", dico)
    print()
     
    from collections import UserDict
     
    vrai_dico = UserDict(eval(dico))
    print("vrai_dico : ", vrai_dico)
    print(vrai_dico["name"])
    Cette dernière est un peu tirée par les cheveux, mais bon.

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 03/12/2008, 16h57
  2. [MySQL] parser pour smiley
    Par zave dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 31/10/2007, 21h29
  3. Un petit Programme sur la Geolocalisation pour le plaisir
    Par blondelle dans le forum C++Builder
    Réponses: 2
    Dernier message: 07/08/2007, 12h58
  4. [Bison] plusieurs parsers pour un meme programme
    Par gedeon555 dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 23/02/2007, 21h20
  5. Utiliser un parser pour extraire des formules
    Par EpOnYmE187 dans le forum C++
    Réponses: 2
    Dernier message: 15/03/2005, 23h55

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