C # Scrape les données de la page wiki (grattage d'écran)

c# html-agility-pack screen screen-scraping

Question

Je veux gratter une page Wiki. Plus précisément, celui-ci.

Mon application permettra aux utilisateurs d'entrer le numéro d'immatriculation du véhicule (par exemple, SBS8988Z) et affichera les informations correspondantes (qui se trouvent sur la page elle-même).

Par exemple, si l'utilisateur entre SBS8988Z dans un champ de texte de mon application, il doit rechercher la ligne sur cette page wiki.

SBS8988Z (SLBP 192/194*) - F&N NutriSoy Fresh Milk: Singapore's No. 1 Soya Milk! (2nd Gen)

et retournez SBS8988Z (SLBP 192/194 *) - Lait frais NutriSoy F & N: le lait de soja n ° 1 de Singapour! (2e génération).

Mon code à ce jour est (copié et édité à partir de divers sites Web) ...

WebClient getdeployment = new WebClient();
string url = "http://sgwiki.com/wiki/Scania_K230UB_(Batch_1_Euro_V)";

getdeployment.Headers["User-Agent"] = "NextBusApp/GetBusData UserAgent";
string sgwikiresult = getdeployment.DownloadString(url); // <<< EXCEPTION
MessageBox.Show(sgwikiresult); //for debugging only!

HtmlAgilityPack.HtmlDocument sgwikihtml = new HtmlAgilityPack.HtmlDocument();
sgwikihtml.Load(new StreamReader(sgwikiresult));
HtmlNode root = sgwikihtml.DocumentNode;

List<string> anchorTags = new List<string>();   

foreach(HtmlNode deployment in root.SelectNodes("SBS8988Z"))
{
    string att = deployment.OuterHtml;
    anchorTags.Add(att);
}

Cependant, je reçois une ArgumentException non gérée - Caractères illégaux dans le chemin.

Quel est le problème avec le code? Y a-t-il un moyen plus facile de faire cela? J'utilise HtmlAgilityPack mais s'il y a une meilleure solution, je serais ravie de la respecter.

Réponse acceptée

Quel est le problème avec le code? Pour être franc, tout. : P

La page n'est pas formatée de la façon dont vous la lisez. Vous ne pouvez pas espérer obtenir le contenu souhaité de cette façon.

Le contenu de la page (la partie qui nous intéresse) ressemble à ceci:

<h2>
<span id="Deployments" class="mw-headline">Deployments</span>
</h2>
<p>
    <!-- ... -->
    <b>SBS8987B</b>
    (SLBP 192/194*)
    <br>
    <b>SBS8988Z</b>
    (SLBP 192/194*) - F&amp;N NutriSoy Fresh Milk: Singapore's No. 1 Soya Milk! (2nd Gen)
    <br>
    <b>SBS8989X</b>
    (SLBP SP)
    <br>
    <!-- ... -->
</p>

En gros, nous devons trouver les éléments b qui contiennent le numéro d’enregistrement que nous recherchons. Une fois que nous avons trouvé cet élément, récupérez le texte et assemblez-le pour former le résultat. Ici c'est en code:

static string GetVehicleInfo(string reg)
{
    var url = "http://sgwiki.com/wiki/Scania_K230UB_%28Batch_1_Euro_V%29";

    // HtmlWeb is a helper class to get pages from the web
    var web = new HtmlAgilityPack.HtmlWeb();

    // Create an HtmlDocument from the contents found at given url
    var doc = web.Load(url);

    // Create an XPath to find the `b` elements which contain the registration numbers
    var xpath = "//h2[span/@id='Deployments']" // find the `h2` element that has a span with the id, 'Deployments' (the header)
              + "/following-sibling::p[1]"     // move to the first `p` element (where the actual content is in) after the header
              + "/b";                          // select the `b` elements

    // Get the elements from the specified XPath
    var deployments = doc.DocumentNode.SelectNodes(xpath);

    // Create a LINQ query to find the  requested registration number and generate a result
    var query =
        from b in deployments                 // from the list of registration numbers
        where b.InnerText == reg              // find the registration we're looking for
        select reg + b.NextSibling.InnerText; // and create the result combining the registration number with the description (the text following the `b` element)

    // The query should yield exactly one result (or we have a problem) or none (null)
    var content = query.SingleOrDefault();

    // Decode the content (to convert stuff like "&amp;" to "&")
    var decoded = System.Net.WebUtility.HtmlDecode(content);

    return decoded;
}


Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow