Laden...

Links aus einer Seite mit dem HtmlAgilityPack auslesen

Erstellt von theSoulT vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.717 Views
T
theSoulT Themenstarter:in
64 Beiträge seit 2018
vor 4 Jahren
Links aus einer Seite mit dem HtmlAgilityPack auslesen

Halo zusammen,

ich benötige mal wieder eure Hilfe 🙂
Nach tagelanger Suche bin ich leider mit meinem Programm noch am Anfang, weil ich hier nicht weiter komme.
Ich möchte von einer Website alle Links auslesen.
Dies habe ich mit folgendem Code versucht:

private void button1_Click(object sender, EventArgs e)
        {
            var url = "https://www.pilz.com/de-DE/search#SEARCH=772100&pilz_group_type=";
            var web = new HtmlWeb();
            var doc = web.Load(url);

            var node = doc.DocumentNode.SelectNodes("//*[@id=\"pilz-fts-search-results-container\"]/a[2]");

            foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//*[@id=\"pilz-fts-search-results-container\"]/a[2]"))
            {
                HtmlAttribute att = link.Attributes["href"];
                if (att.Value.Contains("#"))
                {
                    string[] substring = att.Value.Split('#');
                    Console.ForegroundColor = ConsoleColor.Blue;
                    Console.Write(substring[0]);
                    Console.ReadLine();
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Blue;
                    Console.WriteLine(att.Value);
                    Console.ReadLine();
                }
            }
        }

In der foreach-Schleife bekomm ich ein NullException-Error.
Deshalb habe ich die var node erstellt, um zu sehen ob ich null bekomme, was hier der Fall ist.
Könnt Ihr mir sagen was an dem XPATH nicht in Ordnung ist?

Hier noch der Link zur Website:
https://www.pilz.com/de-DE/search#currentPage=1&SEARCH=772100&search_connector=and

Wenn es genauer geht mit den Links:
Ich möchte die Links in der Mitte haben (Wo ein Pfeil davor ist)

Ich hoffe ihr könnt mir helfen 😁

Grüße
theSoulT

T
theSoulT Themenstarter:in
64 Beiträge seit 2018
vor 4 Jahren

Hallo Abt,
danke für die schnelle Rückmeldung.

Das a[2] hab ich auch schon weggelassen.
Dann ist die NullReferenceException an der Stelle weg, allerdings findet er keine Links und gibt mir bei

                if (att.Value.Contains("#"))

eine NullReferenceException, weil keine Links hier vorhanden sind.

X(

16.806 Beiträge seit 2008
vor 4 Jahren

Was sagt Dein Debugger? Der ist dafür da um zu kontrollieren, was sich wirklich in den Objekten befindet....

[Artikel] Debugger: Wie verwende ich den von Visual Studio? [FAQ] NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt

T
theSoulT Themenstarter:in
64 Beiträge seit 2018
vor 4 Jahren

Hallo Abt,

mein Debugger sagt: "att" war "null".
Und link.Attributes["href"] ist ebenfalls null.

16.806 Beiträge seit 2008
vor 4 Jahren

Dann schau Dir - wie bereits gesagt - mit dem Debugger die Inhalte an.
Wenn Du nicht weißt, wie man den Debugger bedient, dann les Dir bitte den Artikel durch - dafür ist dieser Artikel da.

T
theSoulT Themenstarter:in
64 Beiträge seit 2018
vor 4 Jahren

Ich bin dabei, aber weiß allerdings nicht nach was ich genau suchen soll ?(

T
theSoulT Themenstarter:in
64 Beiträge seit 2018
vor 4 Jahren

Ich habe jetzt mal per HttpWebRequest mir den Code der Website auslesen lassen:


private void button1_Click(object sender, EventArgs e)
        {
            string url = "https://www.pilz.com/de-INT/search#SEARCH=772100&pilz_group_type=";
            
            HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            
            HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
            
            Stream receiveStream = myHttpWebResponse.GetResponseStream();
            Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
            
            StreamReader readStream = new StreamReader(receiveStream, encode);
            Console.WriteLine("\r\nResponse stream received.");
            Char[] read = new Char[256];
            
            int count = readStream.Read(read, 0, 256);
            Console.WriteLine("HTML...\r\n");
            while (count > 0)
            {
                String str = new String(read, 0, count);
                Console.Write(str);
                count = readStream.Read(read, 0, 256);
            }
            Console.WriteLine("");
            
            myHttpWebResponse.Close();
            readStream.Close();
        }

Das Ergebnis war unter anderem:

<form class="treffer">
                            Anzahl der Suchergebnisse <span id="pilz-fts-search-result-amount">123</span>
                            <select id="resultsPerPage" size="1" title="Ergebnisse pro Seite">
                                <option value="10">10</option>
                                <option value="20">20</option>
                                <option value="30">30</option>
                                <option value="40">40</option>
                                <option value="50">50</option>
                            </select>
                        </form>
                        <div id="pilz-fts-search-results-container"></div>
                    </div>
                    <nav>
                        <ul class="pagination" id="pilz-fts-search-pagination-container">

wobei hier ja die Zeile

                        <div id="pilz-fts-search-results-container"></div>

interessant ist. Hier scheint es so, als ob der Bereich dazwischen nicht existiert.
Gerade ist mir ausfgefallen, das wenn ich die Website untersuche und über den Debugger rein geh, sieht es identisch aus wie oben. Über den DOM-Explorer sind allerdings zwischen <div id="pilz-fts-search-results-container"> und </div> noch die Links, welche ich benötige 8o

M
368 Beiträge seit 2006
vor 4 Jahren

Naiver Vorschlag: statt über die URL zu gehen könnte man den Inhalt des DOM-Explorers in eine lokale HTML-Datei speichern. FF -Link zu Pilz- alles markieren - rechte Maustaste - Ausgewählten Quelltext anzeigen. Dort wieder alles markieren und kopieren via Ctrl+C. Macht immerhin 2361 Zeilen vs. 681... Und die Links mit /open/ oder /restricted/ erscheinen auch

Addendum: die Anleitung von wg. lokaler Datei könnte man befolgen C-Sharp Corner - HTML Web Agility Pack

Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉

16.806 Beiträge seit 2008
vor 4 Jahren

Deine Seite verwendet JavaScript und lädt die Ergebnisse nach.
Das ist demnach natürlich auch nur mit einer Bibliothek möglich, die JavaScript unterstützt.

Das macht aber weder der WebRequest noch das Agility Pack.
Daher wird vermutlich Dein XPath auch nichts finden. Aber das hätte man im Debugger gesehen, wenn man sich den Inhalt von doc.DocumentNode ausführlich angeschaut hätte 😉

Die Seite mag oder erlaubt evtl. das automatische Parsen nicht.
Ansonsten würde die Seite ja auch eine API anbieten.

So musst Du nun wohl entweder mit manuellem Parsen arbeiten oder Dir mit JavaScript DOM-Support etwas suchen, zB. WebKit oder Chrome Headless ansprechen.