2017-02-01 40 views
9

Próbuję zautomatyzować niektóre z naszych procesów, jeden obejmuje logowanie się do zewnętrznej strony internetowej, kliknięcie łącza w celu rozwinięcia szczegółów, a następnie pobranie wszystkich wyświetlanych szczegółów.Strona WWW skrobania ekranu zawierająca przycisk z AJAX

Mam proces logowania i mogę pobrać wszystkie szczegóły po ich rozszerzeniu.

Problem polega na kliknięciu łącza. Łącze jest zdefiniowana jak poniżej (usunąłem co metoda Submit faktycznie robi jak kod jest długa i prawdopodobnie nieistotne Oczywiście img jest zastępczy tylko jako przykład.):

<a id="form:SummarySubView:closedToggleControl" onclick="A4J.AJAX.Submit(...); return false;" href="#"> 
    <img ... /> 
</a> 

używam te dane jak poniżej:

void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
{ 
    WebBrowser browser = (WebBrowser)sender; 

    HtmlElement expandDetails = browser.Document.GetElementById("form:SummarySubView:closedToggleControl"); 
    //When open ID for element is "form:SummarySubView:openToggleControl" 

    if(expandDetails == null) //If already expanded 
    { 
     //Stuff 
    } 
    else 
    { 
     expandDetails.InvokeMember("click"); //Click on element to run AJAX 
    } 
} 

Po uruchomieniu expandDetails.InvokeMember("click");browser_DocumentCompleted jest wywoływana ponownie zgodnie z oczekiwaniami, ale dokument jest taka sama jak poprzednio i expandDetails ponownie znaleźć z „zamknięty” id. Oznacza to, że szczegóły, których szukam, nigdy nie są pokazywane.

Jak uzyskać dostęp do dokumentu PO uruchomieniu skryptu AJAX?

Dodawanie pliku Timer do opóźnienia sprawdzania dokumentu nie działa.

Odpowiedz

6

Wydaje się, że naprawdę proste rozwiązanie zadziałało. Mój kod wygląda teraz tak:

void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
{ 
    WebBrowser browser = (WebBrowser)sender; 

    HtmlElement expandDetails = browser.Document.GetElementById("form:SummarySubView:closedToggleControl"); 
    //When open ID for element is "form:SummarySubView:openToggleControl" 

    if(expandDetails == null) //If already expanded 
    { 
     //Stuff 
    } 
    else 
    { 
     expandDetails.InvokeMember("click"); //Click on element to run AJAX 

     while (expandDetails != null) 
     { 
      expandDetails = browser.Document.GetElementById("form:SummarySubView0:closedToggleControl"); 

      Application.DoEvents(); 
      System.Threading.Thread.Sleep(200); 
     } 

     //Stuff 
    } 
} 

Tak działa pętlę while działa dobrze dla mojego przypadku.

+0

Awesome! Cieszę się, że udało ci się. –

1

Po pierwsze, zdarzenie document.complete uruchomi WSZYSTKIE ramki na stronie. Więc jeśli posiadasz 5 elementów iframe, otrzymasz 6 pełnych dokumentów.

Musisz więc sprawdzić, czy rzeczywiście jesteś oknem najwyższego poziomu, czy też nie. Wykonanie tego samodzielnie może rozwiązać problem.

private void WebBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
    { 
     WebBrowser wb = sender as WebBrowser; 
     //check to make sure we are on the TOP-level page. 
     if (wb.Document.Window.Parent == null) 
     { 
      //do whatever else you need to here 
     } 
    } 

Jeśli tego nie zrobisz, możesz po prostu użyć minutnika, aby poczekać kilka sekund po zakończeniu dokumentu.

public partial class Form1 : Form 
{ 
    Timer t; 
    public Form1() 
    { 
     InitializeComponent(); 
     webBrowser1.DocumentCompleted += WebBrowser1_DocumentCompleted; 
    } 
    private void WebBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
    { 
     WebBrowser wb = sender as WebBrowser; 

     //check to make sure we are on the TOP-level page. 
     if (wb.Document.Window.Parent == null) 
     { 
      t = new Timer(); 
      t.Tick += (Timersender, eventargs) => 
      { 
       //do whatever else you need to here 
       t.Stop(); 
      }; 
      t.Interval = 2000; //wait 2 seconds for the document to complete 
      t.Start(); 
     } 
    } 
} 

Można zmodyfikować timer, aby był dłuższy lub krótszy w razie potrzeby. Ale to powinno ci dać to, czego potrzebujesz.

+0

Czy dokument jest kompletny przed zastosowaniem funkcji AJAX? Dam mu szansę ... – anothershrubery

+0

Nie wiem, którą stronę przeglądasz. Mogą je zakodować w dowolny sposób. Ale tak, to jest bardzo możliwe, aby strona internetowa zaczęła wywoływać metody ajaxowe po wywołaniu document.complete przez podpięcie do window.onload z javascript lub $ (document) .ready z jQuery. Mówię tylko, że powinieneś przynajmniej sprawdzić, czy zdarzenie document.complete, które się odpala, pochodzi z okna najwyższego poziomu. A jeśli to nie wystarczy, możesz dodać licznik czasu, aby poczekać kilka sekund, podczas gdy inny ajax się zakończy. –

+0

Tak więc dodałem w "Timer" i nie wydaje się działać. Bez względu na to, jak długo ustawiam opcję "Timer", nadal wyświetla się dokument "wstępnie kliknięty". – anothershrubery