C # Scrape Daten von Wiki-Seite (Screen-Scraping)

c# html-agility-pack screen screen-scraping

Frage

Ich möchte eine Wiki-Seite scrappen. Genauer gesagt, dieser.

Meine App ermöglicht es Benutzern, die Registrierungsnummer des Fahrzeugs (z. B. SBS8988Z) einzugeben, und es wird die zugehörigen Informationen angezeigt (die auf der Seite selbst ist).

Wenn der Benutzer beispielsweise SBS8988Z in ein Textfeld in meiner Anwendung eingibt, sollte er nach der Zeile auf dieser Wiki-Seite suchen

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

und zurück SBS8988Z (SLBP 192/194 *) - F & N NutriSoy Frische Milch: Singapurs Nr. 1 Sojamilch! (2. Generation)

Mein Code ist bisher (kopiert und bearbeitet von verschiedenen Websites) ...

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);
}

Allerdings bekomme ich eine ArgumentException wurde nicht behandelt - Illegale Zeichen im Pfad.

Was ist falsch an dem Code? Gibt es einen einfacheren Weg dies zu tun? Ich benutze HtmlAgilityPack, aber wenn es eine bessere Lösung gibt, würde ich gerne entsprechen.

Akzeptierte Antwort

Was stimmt nicht mit dem Code? Um ehrlich zu sein, alles. : P

Die Seite ist nicht so formatiert, wie Sie sie lesen. Sie können nicht hoffen, den gewünschten Inhalt auf diese Weise zu erhalten.

Der Inhalt der Seite (der Teil, an dem wir interessiert sind) sieht ungefähr so ​​aus:

<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>

Im Grunde müssen wir die b Elemente finden, die die Registrierungsnummer enthalten, die wir suchen. Sobald wir dieses Element gefunden haben, holen wir uns den Text und fügen ihn zusammen, um das Ergebnis zu bilden. Hier ist es in 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

Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum