Partage
  • Partager sur Facebook
  • Partager sur Twitter

Parser de liens d'une page web

    19 août 2006 à 14:31:19

    Bonjour , j'ai créer une fonction qui permet de parser une page html et d'en donner tous ses liens !
    Je me suis basé sur l'algorythme de Knuth-Pratt-Morris... qui est rapide et efficace !
    Alors je demande a tous ceux qui se débrouillent bien en C deme dire si le script est convenable :)

    Voici le code !

    #include <stdio.h>
    #include <stdlib.h>


    void kmp_recherche(char *P, char *S, int T[]);
    void kmp_tableau(char *P, int T[]);

    int main(int argc, char *argv[])
    {
      char *S=NULL, chaine[1000]= " ";
      FILE *fichier=NULL;
      long longueurFichier=0;
      fichier=fopen("fichier.txt", "r");
      if(fichier!=NULL)
      {               
                       
                       fseek(fichier, 0, SEEK_END);
                       longueurFichier=ftell(fichier);
                       rewind(fichier);
                       printf("Longueur : %ld\n", longueurFichier);
                       S=malloc(sizeof(char) * longueurFichier);
                       while(!feof(fichier))
                       {
                                    fread(chaine,1000, 1,fichier);
                                    strcat(S, chaine);
                                    memset(chaine, 0, 1000);
               
               
                       }
                     
      fclose(fichier);   
      }
     
      char P[]="<a *href=";
      int *T;
     
      T=malloc(sizeof(int) * strlen(P));
     
      kmp_tableau(P, T);
     
     
      kmp_recherche(P, S, T);
     
      free(T);
      system("PAUSE");     
      return 0;
    }

    void kmp_recherche(char *P, char *S, int T[])
    {
         
    int m = 0, i=0, j=0, continuer=1;


    while (S[m + i] != '\0')
    {
          if(P[i]=='*')
          {
                       
     
                 if(!(S[m + i]=='h' && S[m + i + 1]=='r' && S[m + i + 2]=='e' && S[m + i + 3]=='f' && S[m + i + 4]=='='))
                 {

                       
                        while(continuer)
                        {
                                     
                                        if(S[m + i + j]==' ')
                                        {
                                             
                                       
                       
                                          if(S[m + i + j + 1]=='h' && S[m + i + j + 2]=='r' && S[m + i + j + 3]=='e' && S[m + i + j + 4]=='f' && S[m + i + j + 5]=='=')
                                          {     
                                                 
                                                 
                                                 continuer=0;
                                                 m+=i + j + 6;
                                                 j=m;
                                                 while(S[j]!='>')
                                                 {
                                                                  j++;
                                                 }
                                                 if(S[j]!='\0')
                                                 {
                                                 printf("lien : ");
                                                 
                                                 for(i=m;i<j;i++)
                                                 {
                                                                 printf("%c", S[i]);
                                                 }
                                                 
                                                 printf("\n");
                                                 m=j + 1;
                                                 }
                                                 
                                                 i=0;
                                                 continuer=0;
                                          }
                                          else
                                          {   
                                         
                                              j++;
                                          }
                                        }
                                        else if(S[m + i + j]=='>')
                                        {
               
                                        m+=i + j + 1;
                                        i=0;
                                        continuer=0;
                                        }
                                        else
                                        {
                                        j++;
                                        }
                        }
                 }
                 else
                 { 
                 
                     m+=i + 5 + 1;
                     j=m;
                     while(S[j]!='>')
                     {
                                     j++;
                     }
                     if(S[j]!='\0')
                     {
                     
                     printf("lien 2: ");
                     for(i=m;i<j;i++)
                     {
                                     printf("%c", S[i]);
                     }
                     printf("\n");
                     i=0;
                     m=j + 1;
                     }
                         
                 
                 }
                 
                 j=0;
                 continuer=1;
          }
         


            if (S[m + i] == P[i])
            {
                ++i;
            }
            else
            {
                m += i - T[i];
                if (i > 0) i = T[i];
            }
           
    }


    }


    void kmp_tableau(char *P, int T[])
    {
        int i = 0;
        int j = -1;
        char c = '\0';
       
        T[0] = j;
        while (P[i] != '\0') {
            if (P[i] == c) {
                T[i + 1] = j + 1;
                ++j;
                ++i;
            } else if (j > 0) {
                j = T[j];
            } else {
                T[i + 1] = 0;
                ++i;
                j = 0;
            }
            c = P[j];
        }
       
        return;
    }




    Voila quelques précisions sur le code :

    Je stock dans la variable S le contenu de fichier.txt qi contient le code source d'une page web.

    dans : P[]="<a *href=";

    le '*' signifie : n'importe quels caracteres qui devront etre suivi d'un espace avant de tomber sur le href=,ou bien aucun caractere, et donc pas d'espace avant le href=.


    Bon je suis un débutant, alors comprenez si le code est pas tres bon :p

    j'attend avec impatience votre avis :)

    a+
    • Partager sur Facebook
    • Partager sur Twitter
      19 août 2006 à 14:48:34

      Je n'ai pas tout lu mais j'ai une petit remarque concernant ce bout de code :


      while(!feof(fichier))
                         {
                                      fread(chaine,1000, 1,fichier);
                                      strcat(S, chaine);
                                      memset(chaine, 0, 1000);
                 
                 
                         }


      Quand tu fais fread tu récupère 1000 caractères (ou octets) dans chaine, mais attention ce n'est pas une chaine de caractère car elle ne se termine pas par 0. Par concéquent il me semble qu'utiliser strcat est impossible. D'autant plus que S n'est je crois pas initialisé à 0 ( *s = '\0'; )

      Question simple maintenant : pourquoi utilises tu un buffer pour stocker le fichier si tu connais la taille du fichier ? Ce qui suit ne suffirait-il pas ?


      S = malloc(taillefichier * sizeof(char)+1);
      fread(S, sizeof(char), taillefichier, fichier);
      /* Attention fread (void *ptr, size_t size, size_t nmemb, FILE *stream); (size c'est la taille d'un char, et nmemb c'est le nombre de char) */
      S[taillefichier] = '\0';


      J'émet aussi une reserve quand à l'utilisation de ftell qui retourne une valeur en octet (je crois) et pas en nombre de caractères. En effet sur certaine implémentation un char peut valoir plus de 1 octet. De plus suivant si tu te trouve sous unix ou windows un retour à la ligne compte pour 1 ou 2 caractères.
      A utiliser avec beaucoup de précautions donc, tout comme fseek.
      • Partager sur Facebook
      • Partager sur Twitter
        19 août 2006 à 15:49:33

        Bonjour, merci beaucoup, mais le buffer c'est juste pour l'exemple que je le prend dans un fichier :D

        merci pour la taille du fichier je suis pas obliger de lire caracteres par caracteres avec fgetc et incrémenté unn compteur quand meme ? Car c'est un peu lourd pour les gros fichiers...

        Comment puis je récupérer en TOUTE efficacité et sureté la taille du fichier ?


        Bon je m'attarde pas trop sur le script du buffer, c'est pas tres important :p

        En fait je demande plutot votre avis sur les deux fonctions qui font la recherche :)


        Vous pouvez me dire votre avis ?
        • Partager sur Facebook
        • Partager sur Twitter
          19 août 2006 à 16:19:40

          Apparement tu n'as pas vraiment besoin de la taille du fichier si ? Sinon fread renvoi le nombre de sizeof(char) correctement lu, c'est aussi une possiblité.
          • Partager sur Facebook
          • Partager sur Twitter
            19 août 2006 à 17:16:26

            Bonjour, ui mais j'aimerais le nombre de char lus en tout, meme ceux qui sont pas corectements lu :p

            j'attend toujours votre avis sur la fonction :(
            • Partager sur Facebook
            • Partager sur Twitter

            Parser de liens d'une page web

            × 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.
            • Editeur
            • Markdown