Analisi con Async, HtmlAgilityPack e XPath

asynchronous c# html-agility-pack web-scraping xpath

Domanda

Ho incontrato un problema piuttosto strano. È molto difficile da spiegare, quindi per favore portami dietro, ma fondamentalmente ecco una breve introduzione:

  • Sono nuovo alla programmazione Async ma non riesco a trovare un problema nel mio codice
  • Ho usato HtmlAgilityPack prima, ma mai la versione .NET 4.5.
  • Questo è un progetto di apprendimento, non sto cercando di grattare o qualcosa del genere.

Fondamentalmente, ciò che sta accadendo è questo: sto recuperando una pagina da internet, caricandola attraverso lo stream in un HtmlDocument , quindi recuperando determinati HtmlNodes da esso usando le espressioni XPath . Ecco un pezzo di codice semplificato:

            myStream = await httpClient.GetStreamAsync(string.Format("{0}{1}", SomeString, AnotherString);

            using (myStream)
            {
                myDocument.Load(myStream);
            }

L'HTML viene ripresentato correttamente, ma gli HtmlNode estratti da XPath stanno subendo un errore di codice HTML. Ecco un esempio di codice HTML che ho ottenuto in risposta a Fiddler:

                    <div id="menu">
   <div id="splash">
      <div id="menuItem_1" class="ScreenTitle"  >Horse Racing</div>
      <div id="menuItem_2" class="Title"  >Wednesday Racing</div>
      <div id="subMenu_2">
         <div id="menuItem_3" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361707-2-20181217-0-0-1-0-0-4020-0-36200255-1-0-0-0-0">21.51 Britannia Way</a></div>
         <div id="menuItem_4" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361710-2-20181217-0-0-1-0-0-4020-0-36200258-1-0-0-0-0">21.54 Britannia Way</a></div>
         <div id="menuItem_5" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361713-2-20181217-0-0-1-0-0-4020-0-36200261-1-0-0-0-0">21.57 Britannia Way</a></div>
         <div id="menuItem_6" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361716-2-20181217-0-0-1-0-0-4020-0-36200264-1-0-0-0-0">22.00 Britannia Way</a></div>
         <div id="menuItem_7" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361719-2-20181217-0-0-1-0-0-4020-0-36200267-1-0-0-0-0">22.03 Britannia Way</a></div>
         <div id="menuItem_8" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361722-2-20181217-0-0-1-0-0-4020-0-36200270-1-0-0-0-0">22.06 Britannia Way</a></div>
      </div>
   </div>
</div>

L'XPath che sto usando è corretto al 100% perché funziona nel browser sulla stessa pagina, ma qui c'è un esempio di a tag che sta recuperando dalla pagina mostrata in precedenza:

<a href="./coupon/?ptid=4020&amp;key=2-70-70-22361710-2-20181217-0-0-1-0-0-4020-0-36200258-1-0-0-0-0"">1.54 Britannia Way</</a>

Ed ecco l'originale che ho copiato dall'alto per semplicità:

<a href="../coupon/?ptid=4020&amp;key=2-70-70-22361710-2-20181217-0-0-1-0-0-4020-0-36200258-1-0-0-0-0">21.54 Britannia Way</a></div>

Come puoi vedere, InnerText è cambiato considerevolmente e ha anche l'URL. Ovviamente il mio programma non funziona, ma non so come. Cosa può causare questo? È un bug in HtmlAgilityPack? Si prega di avvisare! Grazie per aver letto!

Risposta accettata

Dopo molte ore di ipotesi e debug, il problema si è rivelato essere un HtmlDocument che stavo riutilizzando. Ho risolto il problema creando un nuovo HtmlDocument ogni volta che volevo caricare una nuova pagina, invece di usare la stessa.

Spero che questo ti salvi il tempo che ho perso!


Risposta popolare

Non fare l'ipotesi che un'espressione XPath funzioni nel tuo browser ( dopo la conversione DOM , possibilmente caricando i dati con AJAX, ...). Sembra un sito che offre quotazioni di scommesse, immagino che stiano caricando i dati con alcune chiamate javascript.

Verifica se la tua espressione XPath corrisponde al codice sorgente della pagina (come scaricata usando wget o facendo clic su "Visualizza codice sorgente" nel tuo browser - non utilizzare Firebug / ... per questo!

Se il sito utilizza AJAX per caricare i dati, potresti avere fortuna usando Firebug per monitorare quali risorse vengono scaricate mentre la pagina viene caricata. Spesso questi sono file JSON o XML molto facili da analizzare, ed è ancora più facile lavorare con loro che analizzare un sito Web di orribili messagi di HTML.

Aggiornamento: in questo caso speciale, il sito inoltra gli utenti che non inviano un'intestazione Accept-Language a una pagina di selezione della lingua. Invia una tale intestazione per ricevere gli stessi contenuti del browser. In arricciatura, sarebbe simile a questo:

curl -H "Accept-Language: en-US;q=0.6,en;q=0.4" https://mobile.bet365.com/sport/splash/Default.aspx?Sport


Related

Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché