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 :

Aide pour un projet de moteur de recherche interne


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2011
    Messages : 2
    Par défaut Aide pour un projet de moteur de recherche interne
    Bonjour,

    J'ai un petit projet à effecrtuer en langage python. Ce projet consiste à créer une sorte de moteur de recherche, on rentre un mot à rechercher et le programme renverrai si ce mot existe dans le C: et où il se trouve seulement dans les fichiers .txt .
    Pour ceci, il me faut réussir a lister/à obtenir tout les fichiers .txt existant dans le C: et réussir ensuite à aller chercher les mots à l'intérieur de chaque fichier texte.

    Malheuresement, je n'arrive pas à parcourir ou lister tout les fichiers texte de mon C: .
    J'ai deja essayé avec glob.glob, oswalk, os.listdir mais rien de concluant.

    Si quelqu'un pourrait m'aider à résoudre ce problème, ce serait bien sympa
    Pour ce qui est du reste, j'ai déjà avancé car j'arrive à faire marcher ce programme avec un seul fichier seulement.
    Merci d'avance.

    Bonne soirée

  2. #2
    Expert confirmé

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

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

    Avec os.walk, tu avais tout ce qu'il fallait pour parcourir ton arborescence.

    Montres-nous comment tu l'utilise, le problème ne peut-être que là.

  3. #3
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Comme j'avais déjà fait ça pour chercher des mots dans mes sources Python, et que c'est un problème amusant, je propose le petit code (sans prétention) suivant.

    A mon avis, il faut tester chaque entrée dans chaque répertoire séparément, parce que les Windows récents empêchent de rentrer dans certains d'entre eux, et qu'il faut donc gérer ce genre d'erreur.

    En entrée, on a les arguments suivant:

    rep = le répertoire
    mot = le mot à chercher
    select = la liste des motifs à chercher pour les noms de fichier
    sousrep = True si on veut examiner aussi les sous-répertoires
    majusc = True si on veut que les comparaisons soient faites en majuscules

    Bien entendu, si sousrep=True, la recherche est récursive.

    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
     
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    import sys, os
    import fnmatch
     
    ##############################################################################
    def okselect(nf, motifs=["*.txt"]):
        """retourne True si nf satisfait l'un des motifs. False sinon."""
        for motif in motifs:
            if fnmatch.fnmatch(nf, motif):
                return True # on a trouve un motif de selection qui marche
        return False # aucun motif de selection ne marche
     
    ##############################################################################
    def cherchemot(rep, mot="", select=["*.txt"], sousrep=True, majusc=False):
        """Cherche dans rep et ses sous-rep les fichiers qui contiennent le mot"""
     
        if majusc:
            mot = mot.upper()
     
        # lire le contenu du répertoire rep
        try:
            entrees = os.listdir(rep)
        except:
            return [["Erreur: impossible d'entrer dans %s" % rep]]
        listerep = []
        listefic = []
        for entree in entrees:
            if os.path.isdir(os.path.join(rep, entree)):
                listerep.append(entree)
            else:
                if okselect(entree, select):
                    listefic.append(entree)
        listerep.sort()
        listefic.sort()
     
        # cherche les fichiers qui contiennent le mot
        okrep = []
        if mot != "":
            for nf in listefic:
                okfic = []
                nfc = os.path.join(rep, nf)
                f = open(nfc,'r')
                for i, ligne in enumerate(f):
                    if majusc:
                        ligne = ligne.upper()
                    if ligne.find(mot) > 0:
                        if okfic == []:
                            okfic = [nf]
                        okfic.append(i+1)
                f.close()
                if okfic != []:
                    if okrep == []:
                        okrep = [[rep]]
                    okrep[-1].append(okfic)
     
        # traitement récursif des sous-répertoires si c'est demandé
        if sousrep:
            for repert in listerep:
                r = cherchemot(os.path.join(rep, repert), mot, select, sousrep, majusc)
                if r != []:
                    okrep += r
     
        return okrep
    Exemple d'utilisation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    repert = "C:"
    mot = "import"
    select = ["*.py", "*.pyw"]
    sousrep = True
    majusc = True
     
    okreps = cherchemot(repert, mot, select, sousrep, majusc)
    le résultat okreps est une liste de répertoires avec pour chacun d'entre eux la liste des fichiers qui ont le mot avec la liste des numéros de lignes. Bien entendu:

    - seuls les répertoires qui ont au moins un fichier qui va sont mentionnés.

    - seuls les fichiers qui ont le mot au moins 1 fois sont mentionnés

    Voilà comment on affiche le résultat:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for okrep in okreps:
        print
        for okfic in okrep:
            print okfic
    Et voilà un extrait de résultat:

    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
     
    ...
    C:Python27\Lib\xml\parsers
    ['expat.py', 4]
     
    C:Python27\Lib\xml\sax
    ['__init__.py', 22, 23, 24, 37, 38, 39, 56, 59, 82, 83, 85, 99, 100, 105]
    ['_exceptions.py', 4, 129]
    ['expatreader.py', 8, 9, 10, 11, 12, 13, 15, 22, 23, 28, 37, 38, 42, 410]
    ['handler.py', 51]
    ['saxutils.py', 18, 21, 88]
    ['xmlreader.py', 6, 116]
     
    C:Python27\Scripts
    ['apirst2html.py', 22, 37]
    ['epydoc.py', 15]
    ['epydoc.pyw', 15]
    ['f2py.py', 10, 15, 18, 20]
    ['ipcluster.py', 16, 20]
    ['ipcontroller.py', 14, 18]
    ['ipengine.py', 14, 18]
    ['iptest.py', 6]
    ['ipython-wx.py', 9]
    ['ipython_win_post_install.py', 16]
    ['ipythonx.py', 9]
    ['irunner.py', 7]
    ['pywin32_postinstall.py', 69, 70, 89, 90, 104, 130, 131, 138, 167, 176, 189, 223, 248, 250, 251, 252, 259, 266, 285, 286, 313, 465, 468, 469, 475, 574]
    ...
    Erreur: impossible d'entrer dans C:PerfLogs
    ...
    On voit que l'impossibilité d'entrer dans l'un des répertoires est signalée.

    Sur mon C: de 240Go, cette recherche prend 5 minutes, ce qui est tout de même assez rapide.

    Ce code est très simplifié sur les points suivants:

    - il ne tient pas compte des encodages des fichiers: attention donc aux mots contenant des caractères accentués. Mais pour la recherche, il faudrait un "renifleur" d'encodage, car on ne sait pas d'avance si c'est, par exemple, du cp1252 (encodage windows), du cp850 (encodage DOS) ou de l'utf-8.

    - De même la comparaison en majuscule devrait neutraliser ces caractères accentués (j'ai une telle fonction si cela t'intéresse).

    - on pourrait avoir pour la recherche non pas une seul mot, mais une formule avec plusieurs mots reliés par des ET et des OU.

    Sans compter que pour une recherche rapide, il faudrait conserver et mettre à jour en tâche de fond les résultats pour ne pas avoir à tout tester à chaque fois.

    Bref, pour un code complet et "pro", il y a du boulot...

    Tyrtamos

  4. #4
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Bonjour.

    Citation Envoyé par tyrtamos Voir le message
    Il ne tient pas compte des encodages des fichiers: attention donc aux mots contenant des caractères accentués. Mais pour la recherche, il faudrait un "renifleur" d'encodage, car on ne sait pas d'avance si c'est, par exemple, du cp1252 (encodage windows), du cp850 (encodage DOS) ou de l'utf-8.
    Le module chardet propose cela.

    Citation Envoyé par tyrtamos Voir le message
    De même la comparaison en majuscule devrait neutraliser ces caractères accentués...
    Je suis intéressé.

    Citation Envoyé par tyrtamos Voir le message
    On pourrait avoir pour la recherche non pas une seul mot, mais une formule avec plusieurs mots reliés par des ET et des OU.
    Pourquoi pas utiliser les regex avec toute la puissance que cela fournit ?

    Citation Envoyé par tyrtamos Voir le message
    Sans compter que pour une recherche rapide, il faudrait conserver et mettre à jour en tâche de fond les résultats pour ne pas avoir à tout tester à chaque fois.
    Cela pourrait être l'occasion d'utiliser une base de donnée.

    Je ne fais que lancer des idées...

  5. #5
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour rambc,

    Pour la conversion de chaines quelconques en majuscules non accentuées, voilà la fonction que j'utilise. Attention: il ne faut pas l'utiliser en utf-8 mais soit en latin1 (par exemple), soit en unicode.

    J'ai retenu les accents habituels du français, avec en plus:

    - 'åÅ' qu'on rencontre dans certains noms de pays (les îles d'ÅLAND par exemple)
    - 'ÿŸ' qu'on rencontre dans certains noms propres, y compris noms de villes (L'Haÿ-les-Roses)
    J'ai laissé les 2 caractères liés: 'æ' et 'œ' sans chercher à les séparer.

    Attention: tel qu'écrit, le code laissera passer tel quel un caractère ne faisant pas partie de alpha1. Cela peut être un caractère majuscule non accentué ('A', 'B', ...), mais aussi un caractère étranger au français ('Ž', ' Š', 'ñ', ...), et, bien sûr, n'importe quel caractère non alphabétique ('€', ';', ...). Pour un autre usage, rien n'empêche de générer une exception dans ces cas-là.

    Version unicode:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    def majusc_sans_accent(ch):
        """Convertit la chaine de caractères ch en majuscules non accentuées """
        alpha1 = u"aàÀâÂäÄåÅæbcçÇdeéÉèÈêÊëËfghiîÎïÏjklmnoôÔöÖœpqrstuùÙûÛüÜvwxyÿŸz"
        alpha2 = u"AAAAAAAAAÆBCCCDEEEEEEEEEFGHIIIIIJKLMNOOOOOŒPQRSTUUUUUUUVWXYYYZ"
        x = u""
        for c in ch:
            k = alpha1.find(c)
            if k >= 0:
                x += alpha2[k]
            else:
                x += c
        return x
    Tyrtamos

  6. #6
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Merci.

    Il y a aussi maketrans du module string : http://docs.python.org/library/strin...ring.maketrans .

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

Discussions similaires

  1. Recherche aide pour conception projet
    Par Christophe FRT dans le forum Débuter
    Réponses: 2
    Dernier message: 14/10/2008, 11h10
  2. Je recherche une aide pour un projet en VB 6
    Par nadège31 dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 12/01/2007, 19h42
  3. Besoin d'aide pour un projet
    Par ZiMo dans le forum Linux
    Réponses: 9
    Dernier message: 24/10/2005, 00h28
  4. Besoin d'aide pour un projet de jeu en ligne
    Par FLEO dans le forum Projets
    Réponses: 1
    Dernier message: 21/10/2005, 08h55
  5. [CAML] Recherche aide pour un projet
    Par tarzoon dans le forum Caml
    Réponses: 1
    Dernier message: 02/09/2005, 10h32

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