Vinnaren i pepparkakshustävlingen!
2016-07-19, 17:48
  #1
Medlem
Tänkte dela med mig av en fungerande lösning där man med hjälp av HtmlAgilitypack kan parsa genom sidor som laddas med DOM-object, t.ex. youtube. För att göra detta använder jag mig av winforms.

Jag har en enkel form med en webbrowser-kontroll. I codebehind navigerar jag till sidan i fråga:

Kod:
webBrowser1.Navigate(url);
webBrowser1.DocumentCompleted += WebBrowser1OnDocumentCompleted;

Bara för att dokumentet är laddat innebär det inte att DOM-objekten är klara. Så i WebBrowser1OnDocumentCompleted lägger jag till en do-while.

Kod:
do
{
var 
documentAsIHtmlDocument3 = (mshtml.IHTMLDocument3)webBrowser1.Document.DomDocument;
WebDocument.LoadHtml(documentAsIHtmlDocument3.documentElement.outerHTML);
await Task.Delay(1000);
} while (!
CheckIfDocumentIsLoaded()); 

Jag har satt WebBrowser1OnDocumentCompleted async. Anledningen till detta är att jag vill använda mig av Task.Delay. Det gör att webbrowsern kan fortsätta laddas under tiden jag gör en paus från att ny kod ska köras. Använder jag Thread.Sleep så kommer inte sidan att laddas under tiden.

Jag laddar in Html till ett HtmlDocument som jag kontrollerar i CheckIfDocumentIsLoaded. Här är det lättast att leta reda på en referenstext eller liknande som alltid har liknande struktur. När AJAX är klart så kommer innehållet att ändras, och då kan man gå ut ur do-while. Exempel:

Html innan AJAX är klar:
Kod:
<h1>{object.Comment.Header}</h1>

När AJAX är klart:
Kod:
<h1>Comments</h1>

Detta är lite grovt exempel, men kan kanske förhindra några gråa hårstrån. Finns andra alternativ på nätet, men ingen fungerade för mig, bara denna lösning.
__________________
Senast redigerad av Proton 2016-07-19 kl. 21:26.
Citera
2016-07-19, 22:19
  #2
Medlem
Tja... du gör nog lite fel (eller mycket).

DocumentCompleted kan anropas flera gånger medan sidan laddas så du måste kolla på ReadyState.
Typ göra så i DocumentCompleted event:
Kod:
if (browserControl.ReadyState != System.Windows.Forms.WebBrowserReadyState.Complete)

det kan också spara lite tid att kolla på nulls innan
Kod:
if ( webBrowser1.Document != null && webBrowser1.Document.Body != null )

Hamnar den på fel kod så sk*ter du i den och väntar på nästa anrop. Ingen while-delay-do madness.
Gör så det fungerar utan async först ;)
Citera
2016-07-20, 01:50
  #3
Medlem
Citat:
Ursprungligen postat av wot34man
Tja... du gör nog lite fel (eller mycket).

DocumentCompleted kan anropas flera gånger medan sidan laddas så du måste kolla på ReadyState.
Typ göra så i DocumentCompleted event:
Kod:
if (browserControl.ReadyState != System.Windows.Forms.WebBrowserReadyState.Complete)

det kan också spara lite tid att kolla på nulls innan
Kod:
if ( webBrowser1.Document != null && webBrowser1.Document.Body != null )

Hamnar den på fel kod så sk*ter du i den och väntar på nästa anrop. Ingen while-delay-do madness.
Gör så det fungerar utan async först

Du måste anropa den flera ggr. Många ggr anropas AJAX först när allt är laddat och klart. Det är en anledning till Task.Delay, för att slippa onödiga anrop. Async måste du ju köra för att webbrowsern ska fortsätta ladda. Men förbättringar är alltid välkomna
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback