2010-11-23 6 views
0

Dans le post suivant j'ai suivi les exemples pour créer mes HttpRequest et les fichiers liste de répertoire webServer: C# HttpWebRequest command to get directory listingHttpWebRequest commande pour obtenir liste des répertoires

J'essaie d'utiliser l'exemple là pour lister les fichiers de mon serveur web . Je peux lister les fichiers du serveur d'exemple cité sur le lien, mais mon serveur affiche juste le dernier fichier ajouté. Mon code est exactement comme l'exemple ici. J'ai remarqué que mon code html est un peu différent. Quelqu'un a une idée:

<html> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
    <title>186.215.156.154 - /download/Zatix/Zatix - Satisfação Geral/</title> 
</head> 
<body> 
    <h1> 
     186.215.156.154 - /download/Zatix/Zatix - Satisfação Geral/</h1> 
    <hr> 
    <pre> 
    <a href="/download/Zatix/">[Para a pasta superior]</a> 
    <br> 
    <br> 
    sexta-feira, 19 de novembro de 2010 11:17  52355 <a href="/download/Zatix/Zatix%20-%20Satisfa%C3%A7%C3%A3o%20Geral/Zatix%20-%20Satisfa%C3%A7%C3%A3o%20Geral_3_00.zip">Zatix - Satisfação Geral_3_00.zip</a><br>sexta-feira, 19 de novembro de 2010 11:17  52355 <a href="/download/Zatix/Zatix%20-%20Satisfa%C3%A7%C3%A3o%20Geral/Zatix%20-%20Satisfa%C3%A7%C3%A3o%20Geral_4_00.zip">Zatix - Satisfação Geral_4_00.zip</a> 
    <br> 
</pre> 
    <hr> 
</body> 
</html 

Je pense que je dois changer quelque chose dans le retour de la méthode GetDirectoryListingRegexForUrl.

Mon code est quelque chose comme ceci:

private string GetDirectoryListingRegexForUrl(string url) 
{ 
    if (url.Equals(Url)); 
    { 
     return "<A HREF=\".*\">(?<name>.*)</A>";     
    } 
    throw new NotSupportedException(); 
} 

public void ListStudies() 
{ 
    Url = BaseUrl + this.clientName + "/" + this.activeStudy + "/"; 
    Console.WriteLine(Url); 
    CookieContainer cookies; 
    HttpWebResponse response; 
    HttpWebRequest req = (HttpWebRequest)System.Net.WebRequest.Create(Url);    

    req.Credentials = _NetworkCredential; 
    req.CookieContainer = new CookieContainer(); 
    req.AllowAutoRedirect = true; 
    cookies = req.CookieContainer; 

    try 
    { 
     response = (HttpWebResponse)req.GetResponse(); 

     if (response.StatusCode != HttpStatusCode.OK) 
      Console.WriteLine("URL NÃO RESPONDEU"); 
     else 
      Console.WriteLine("URL OK"); 

     using (response) 
     { 
      using (StreamReader reader = new StreamReader(response.GetResponseStream())) 
      { 
       string html = reader.ReadToEnd(); 
       Regex regex = new Regex(GetDirectoryListingRegexForUrl(Url)); 
       MatchCollection matches = regex.Matches(html);            

       if (matches.Count > 0) 
       { 
        foreach (Match match in matches) 
        { 
         if (match.Success) 
         { 
          Console.WriteLine(match.Groups["name"]);          
         }         
        } 
       } 
      } 
     } 
    } 
    catch (Exception e) 
    { 
     MessageBox.Show(e.Message, "Update Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
    }    
} 

J'espère que vous pouvez me aider! Merci.

Répondre

1

Deux problèmes majeurs ici.

1). La sortie d'une requête comme celle-ci est complètement arbitraire et n'est même pas garantie. C'est la préoccupation du serveur.

2). Regex est not a suitable means pour analyser HTML ou toute structure similaire, car ce n'est pas une grammaire régulière. Votre meilleur pari en supposant que vous avez une quelconque fiabilité dans votre réponse est de s'appuyer sur quelque chose comme le HtmlAgilityPack pour appliquer un document XHTML rigoureux (peut ne pas être requis si vous êtes chanceux) et le lire comme un document XML avec des requêtes XPath . de retirer le contenu qui vous intéresse

1

Voici la regex correcte:

<A HREF=\".*?\">(?<name>.*?)</A> 

Comparer à l'original:

<A HREF=\".*\">(?<name>.*)</A> 

le problème est avec les opérateurs de répétition .* qui sont gourmands par défaut. Greedy signifie que l'expression rationnelle va s'étendre aussi loin que possible tout en cherchant un match. Ce qui signifie qu'il commencera avec le premier <A et se terminera par le dernier A> dans la chaîne laissant tout entre. Ce 'tout' comprend les autres <A...A> au milieu.

Vous devez spécifier que les opérateurs de répétition sont paresseux. Vous le faites en leur ajoutant ? comme .*?.

P.S. Parsing HTML avec des expressions régulières est notoirement une mauvaise idée. C'est bien si vous avez besoin d'une solution rapide et sale, mais un non-aller pour une solution à long terme. Ajoutez à cela le fait que dans votre cas, la sortie variera par serveur et probablement par version de serveur. Le code n'est pas universellement fonctionnel. S'il vous plaît envisager l'autre approche comme la négociation avec le serveur directement pour obtenir une liste de répertoires (si vous avez l'accès bien sûr).

Et enfin une lecture drôle au thema:

Parsing Html The Cthulhu Way

RegEx match open tags except XHTML self-contained tags

+0

Merci beaucoup, je gaspillées beaucoup de temps en utilisant l'expression régulière plus tôt et il a toujours retourné 1 résultat. L'expression régulière mise à jour donnée par vous, fonctionne génial. –

Questions connexes