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 :

récupérer les mots en gras d'un text


Sujet :

Python

  1. #21
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Wiztiti
    Ça ne fonctionne que si on suppose que les balises sont bien formées:
    En l'occurrence elles le seront forcément sauf si l'utilisateur copie mal le code source et dans ce cas, paf message d'erreur ! Tandis qu'avec BeautifulSoup ben il retourne une liste vide.

    Après côté performances, il faut déjà balayer la chaîne de caractères 1 fois pour la découper puis une autre fois pour extraire les mots.
    Si la chaîne de caractères est de longueur N, on a une complexité en 2xN

    Si on cherche <b> puis à partir de là le </b> qui suit, on ne la parcourt qu'une seule fois et la complexité est N.
    Effectivement même si c'est pas exactement 2xN.
    'toto<b>GRAS</b>titi'
    → 'ttoottoo<b>GRAS</b>titi'

    Tu ferais comment en 1N, ça m'intéresse. =)

    Ma proposition sinon est 150x plus rapide que BeautifulSoup à priori, j'ai abandonné les bibliothèques spécialisées à cause de ça ! Alors oui c'est sûr c'est pas aussi safe mais la sécurité est l'ennemi de la vitesse - Ayrton Senna (ou pas).

    Citation Envoyé par Wiztiti
    insulte sa mémoire quelque peu....
    Non mais dites donc ! Moi j'ai jamais cru que l'univers était statique ne me rabaisse pas à lui !




    Citation Envoyé par Hominidé
    Spontanément j'utiliserai les expressions régulières
    J'ai pas de chat, je ne peux pas... (Tu l'as ?)

  2. #22
    Membre Expert
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    926
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 926
    Billets dans le blog
    8
    Par défaut
    Citation Envoyé par LeNarvalo
    J'ai pas de chat, je ne peux pas... (Tu l'as ?)
    ??

  3. #23
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    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 790
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Tu ferais comment en 1N, ça m'intéresse. =)
    On cherche "<b>" puis à partir de cette position, le "</b>" qui suit, s'il existe.

    str.find et str.index ont des paramètres optionnels (start, end) pour passer l'indice à partir duquel rechercher (et s'arrêter).

    Plus instructif serait de ne pas utiliser ces méthodes pour écrire un petit automate qui lise caractère par caractère et changement d'état.

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

  4. #24
    Invité
    Invité(e)
    Par défaut
    @Hominidé
    https://www.fondamentaux.org/wp-cont...x-768x769.jpeg

    @Wiz
    pour passer l'indice à partir duquel rechercher (et s'arrêter)
    On ne peut pas savoir où s'arrêter mais effectivement on peut lui dire où commencer plutôt que de faire du text[i:].index('</b>') comme je fais habituellement.

    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
    def t2():
    	text = '<b></b>toto<b>GRAS</b><b>BOLD</b>titi<b></b>'
    	i = 3            #On commencera le text à partir de l'indice 3
    	n = len(text)    #Nb de caractères
    	liste = []       #Liste de stockage des mots en gras
    	opened = False   #True si balise ouvrante détectéé
    	while i<n:
    		#Si les 3 caractères précédents valent '<b>' ...
    		if text[i-3:i] == '<b>':
    			liste.append('')
    			opened = True
    		#Si les 4 caractères suivants valent '</b>' ...
    		if text[i:i+4] == '</b>':
    			opened = False
    			i+=3
    		#Si balise GRAS ouvrante détectée ...
    		if opened:
    			liste[-1] += text[i]
    		i+=1
    	return liste
    Seulement 6 fois plus lent que la compréhension de liste donc encore bien plus rapide que BeautifulSoup.
    Y a moyen de faire mieux ? J'ai essayé avec for i, char in enumerate(text) mais je n'ai pas réussi à passer les caractères '</b>' (i+=4)

  5. #25
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    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 790
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    J'ai essayé avec for i, char in enumerate(text) mais je n'ai pas réussi à passer les caractères '</b>' (i+=4)
    devrait suffire après, pour traiter caractère par caractère avec une mémoire, il y a du boulot et c'est l'intérêt de l'exercice.

    Quelque chose comme text[i-3:i] == '<b>' extrait la sous-chaine de 4 caractères.... et donc on balaie bien plus de caractères que la chaîne en contient.

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

  6. #26
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 314
    Par défaut
    Hello,
    Citation Envoyé par LeNarvalo Voir le message
    Ma proposition sinon est 150x plus rapide que BeautifulSoup à priori, j'ai abandonné les bibliothèques spécialisées à cause de ça ! Alors oui c'est sûr c'est pas aussi safe mais la sécurité est l'ennemi de la vitesse - Ayrton Senna (ou pas).
    Je ne sais pas comment tu as fais le calcul de performance mais moi je ne trouve pas ce genre d'écart. Si tu as utilisé des boucles, dans la boucle il ne faut pas inclure le temps de chargement du contenu HTML. On ne le compte qu'une seule fois.
    Voici un test de performance en utilisant beautifulsoup, les expressions régulières, lxml, le code de LeNarvalo avec en entrée la page HTML https://www.developpez.net/forums/d2...s-gras-d-text/
    Dans le test je fais une boucle de 1000 itérations sur la recherche des balises <b>.
    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
    from bs4 import BeautifulSoup
    from lxml.html import fromstring
    import time
    import re
    htmlfile = "d:/temp/test.html"
    markup = open(htmlfile)
    htmlString = markup.read()
    markup.close()
    start = time.time()
    soup = BeautifulSoup(htmlString,'html.parser')
    for i in range(1000):
        motsEnGras = soup.findAll('b')
    end = time.time()
    print("temps de recherche beautifulsoup : " + str(end-start) + " secondes")
    print("beautifulsoup a trouvé " + str(len(motsEnGras)) + " balises")
    print(motsEnGras)
    regex = '<b>(.+?)</b>'
    start = time.time()
    for i in range(1000):
     match = re.findall(regex, htmlString)
    end = time.time()
    print("temps de recherche regex : " + str(end-start) + " secondes")
    print("regex a trouvé " + str(len(match)) + " balises")
    print(match)
    innerTree = fromstring(htmlString)
    start = time.time()
    for i in range(1000):
     bolds = innerTree.cssselect('b')
    end = time.time()
    print("temps de recherche lxml : " + str(end-start) + " secondes")
    print("lxml a trouvé " +  str(len(bolds))  + " balises" )
    print( [mot.text_content() for mot in bolds])
    start = time.time()
    for i in range(1000):
        listeMots = [obj[obj.index('<b>')+3:] for obj in htmlString.split('</b>')[:-1]]
    end = time.time()
    print("temps de recherche du code de LeNarvalo : " + str(end-start) + " secondes")
    print("Le code de LeNarvalo a trouvé " + str(len(listeMots))  + " balises")
    print(listeMots)
    Résultats :
    temps de recherche beautifulsoup : 1.2977912425994873 secondes
    beautifulsoup a trouvé 64 balises
    temps de recherche regex : 0.2655637264251709 secondes
    regex a trouvé 66 balises
    temps de recherche lxml : 0.12497472763061523 secondes
    lxml a trouvé 64 balises
    temps de recherche du code de LeNarvalo : 0.374908447265625 secondes
    Le code de LeNarvalo a trouvé 66 balises
    A noter que la différence du nombre de balises trouvées vient du fait qu'il y a deux balises qui se trouvent en dehors du corps du HTML (<body>). regex et le code de Narvalo ne transforment pas non plus les codes des accents HTML ce que font beautifulsoup et lxml ( ex : install&eacute; -> installé).
    Ami calmant, J.P

  7. #27
    Invité
    Invité(e)
    Par défaut
    Oui j'ai inclut l'ouverture du fichier.
    Je me suis dit que BeautifulSoup prétrie les données à l'ouverture ?


    Je pense qu'ainsi le code ça sera plus rapide :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    listeMots = [obj[:obj.index('</b>')] for obj in htmlString.split('<b>')[1:]]
    Il est plus fréquent de voir un mot en gras que toute un paragraphe. ^^

Discussions similaires

  1. Réponses: 5
    Dernier message: 08/11/2017, 20h44
  2. Réponses: 2
    Dernier message: 22/11/2006, 13h09
  3. Réponses: 4
    Dernier message: 03/08/2006, 17h25
  4. Récupérer les mot-clés Google, est-ce possible ?
    Par kurtalis dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 12/05/2006, 19h48
  5. prob affichage mot en gras dans un texte
    Par klik dans le forum XML/XSL et SOAP
    Réponses: 6
    Dernier message: 13/07/2005, 09h38

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