READYSTATE_COMPLETE bir defa çok gerçekleşiyorsa

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Lord_Ares
Üye
Mesajlar: 1070
Kayıt: 15 Eki 2006 04:33
Konum: Çorlu

READYSTATE_COMPLETE bir defa çok gerçekleşiyorsa

Mesaj gönderen Lord_Ares »

Merhaba
Html parse etmek istediğim bu sayfanın http://www.birebin.com/iddaa/tahminler complete olduğunu bir türlü yakalayamıyorum. Çünkü sayfa birden çok complete gerçekleştiriyor. Bende sayfanın ondocumentcomplete kısmında aratarak yakalamaya çalışıyorum fakat sonuç olumsuz.

Kod: Tümünü seç

  while not xIslemTamam do begin
  Application.ProcessMessages;
  Sleep(1);
     if Pos(Sayfada_Ara,Form1.WebBrowser1.Oleobject.Document.Body.InnerHTML)>0 then begin
       xIslemTamam:=true;
     end ;
  end;
Procedürüm bu şekilde:

Kod: Tümünü seç

procedure Test_Birebin_herkez;
Const
  Sonuc = '<div class="col eIcon">';
Var
  i : Integer;
  strAra, strBlok : String;
  strBaslik, strIlanID,  Kodu, Takim, tahmini,aranacak : String;
begin
  Form1.WebBrowser1.Navigate( 'http://www.birebin.com/iddaa/tahminler' );
  Sayfada_Ara:='<div class="col eIcon">' ;
  xIslemTamam:=false;
  while Form1.WebBrowser1.ReadyState <> READYSTATE_COMPLETE do
  begin
    Application.ProcessMessages;
    Sleep(1);
  end ;

       if xIslemTamam then
        begin
          ShowMessage('ok');
        end;
end;

Nerede hata yaptığımı bulamadım. Sayfa birden çok complete olduğu için ilk arama sonucunda xislemtamam sürekli false dönüyor sanırım.
Bu kontrolü sağlayacak nasıl bir kod yazmalıyım.
teşekkürler
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: READYSTATE_COMPLETE bir defa çok gerçekleşiyorsa

Mesaj gönderen mrmarman »

Asıl sorun, sayfa tamam olduğu halde içerik akışının sona ermemesi. AJAX olayı yani...

Aşağıdaki örnekte 2000 milisaniye yani 2 saniye içinde yeni veri gelmezse işlem tamam varsayan bir yapı örneği göreceksin. Bu yapı işini görecektir. :idea:

Kod: Tümünü seç

procedure TForm1.BitBtn1Click(Sender: TObject);
Const
  MiliSaniyeBekleme = 2000;
Var
  boolDongudenCik : Boolean;
  ZamanBasla      : Cardinal;
  strOncekiIcerik : String;
begin
  WebBrowser1.Silent := True;
  WebBrowser1.Navigate(' http://www.birebin.com/iddaa/tahminler');
  while WebBrowser1.ReadyState <> READYSTATE_COMPLETE do
  begin
    Application.ProcessMessages;
    Sleep(1);
  end;

  // Normal bir şekilde bekledik. Şimdi içeriğin dolmasını bekleyeceğiz.
  boolDongudenCik := False;
  strOncekiIcerik := WebBrowser1.OleObject.Document.Body.InnerHTML;
  while NOT boolDongudenCik do
  begin
    ZamanBasla    := GetTickCount;
    while GettickCount < (ZamanBasla + MiliSaniyeBekleme) do
    begin
      Application.ProcessMessages;
      Sleep(1);
    end;
    // MiliSaniyeBekleme süresi içinde HTML içeriğinde değişme olmamışsa
    // Varsayıyoruz !!! ki tüm veri akışı tamamlanmıştır..
    // Tabi bir varsayım. Ağ hatası da olabilir ama elden ne gelir... :)
    if WebBrowser1.OleObject.Document.Body.InnerHTML = strOncekiIcerik
      then boolDongudenCik := True
      else strOncekiIcerik := WebBrowser1.OleObject.Document.Body.InnerHTML;
  end;
  ShowMessage('Sayfa kesin tamam, herhalde :)';
end;
Resim
Resim ....Resim
Lord_Ares
Üye
Mesajlar: 1070
Kayıt: 15 Eki 2006 04:33
Konum: Çorlu

Re: READYSTATE_COMPLETE bir defa çok gerçekleşiyorsa

Mesaj gönderen Lord_Ares »

Marman hocam zekici bir yaklaşımla nefis bir örnek sunmuşsun ellerine sağlık. Anladığım kadarıyla temel mantık , pos ile sayfa içindeki sabiti takip etmek yerine , belli sürelerde tüm içeriği karşılaştırarak, akışın sonlanıp-sonlanmadığını takip ediyoruz. Açılan sayfa belli süreler içinde, sayfanın bazı yerlerini ajax ile yeniliyor ise bu akşın sürekliliğini saylayacağı için beklenecek süreyi kısa tutmam da yarar var sanırım..
Çok teşekkürler..


ShowMessage('Sayfa kesin tamam, herhalde :)';
( Hocam , kodun içinde paylaştığınız , gülümseten mesajlar günün yorgunluğuna birebir iyi geliyor.. :D )
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: READYSTATE_COMPLETE bir defa çok gerçekleşiyorsa

Mesaj gönderen mrmarman »

Lord_Ares yazdı:Marman hocam zekici bir yaklaşımla nefis bir örnek sunmuşsun ellerine sağlık. Anladığım kadarıyla temel mantık , pos ile sayfa içindeki sabiti takip etmek yerine , belli sürelerde tüm içeriği karşılaştırarak, akışın sonlanıp-sonlanmadığını takip ediyoruz. Açılan sayfa belli süreler içinde, sayfanın bazı yerlerini ajax ile yeniliyor ise bu akşın sürekliliğini saylayacağı için beklenecek süreyi kısa tutmam da yarar var sanırım..
Çok teşekkürler..

ShowMessage('Sayfa kesin tamam, herhalde :)';
( Hocam , kodun içinde paylaştığınız , gülümseten mesajlar günün yorgunluğuna birebir iyi geliyor.. :D )
Mantık tam anladığın şekilde. Sadece süreyi daha kısa tutmak avantaj olmaz. İlk bekleme anında bitti var sayar. Yani ne kadar uzun olursa o kadar kesin sonuç elde edilir. Tabi kullanıcıyı da boşuna bekletmemek lazım.

- Şöyle de yapılabilir.
(1) ilk READY_STATE bloğu var ya, oradan önce ve sonra olmak üzere iki tane GetTickCount alırsın.
(2) Bunların farkını alınca yaklaşık olarak network hızı anlaşılmış olur. Cep telefonu ise şebeke zayıfsa vs. yavaş olur mesela.
(3) CONST olan MiliSaniyeBekleme değişkenini VAR bloğuna alıp, bekleme aralığını belirlemek için sorgu başına elde edeceğin bu farkı MiliSaniyeBekleme değişkenine verirsen dinamik bir yapı kurmuş olursun.
(4) Yani hızlı sistemlerde az bekleme süresi, yavaş sistemlerde çok bekleme süresi şeklinde. Yani süreyi ilk sorgu belirleyecek...

Daha akıllı çözümler de kurulabilir. Bu sadece bir örnek. :idea:
Resim
Resim ....Resim
Lord_Ares
Üye
Mesajlar: 1070
Kayıt: 15 Eki 2006 04:33
Konum: Çorlu

Re: READYSTATE_COMPLETE bir defa çok gerçekleşiyorsa

Mesaj gönderen Lord_Ares »

Çok teşekkürler hocam. Vermiş olduğun kodu fonksiyon olarak kullandım çokta güzel çalıştı. Parse işleminde kullanmak isteyen arkadaşlar için paylaşıyorum.
Şu şekilde kullandım.

Fonksiyon olarak

Kod: Tümünü seç

Function Sayfa_yuklendimi(Adres:string):boolean ; /// true yada false bir değer döndür
Const
  MiliSaniyeBekleme = 2000;
Var
  boolDongudenCik, Durum : Boolean;
  ZamanBasla             : Cardinal;
  strOncekiIcerik        : String;
begin
  Durum:=False;
  Form1.WebBrowser1.Silent := True;
  Form1.WebBrowser1.Navigate(Adres);

  while Form1.WebBrowser1.ReadyState <> READYSTATE_COMPLETE do
  begin
    Application.ProcessMessages;
    Sleep(1);
  end;
  boolDongudenCik := False;
  strOncekiIcerik := Form1.WebBrowser1.OleObject.Document.Body.InnerHTML;
  while NOT boolDongudenCik do
  begin
        ZamanBasla:= GetTickCount;
        while GettickCount < (ZamanBasla + MiliSaniyeBekleme) do
        begin
          Form1.StatusBar1.Panels[0].Text:='Yükleniyor..';//Dileyen  silebilir. Kullanacak arkadaşlar status barın panels özelliğine tıklayın çıkan ekranda yeni bir tane yaratın
          Application.ProcessMessages;
          Sleep(1);
        end;
        if Form1.WebBrowser1.OleObject.Document.Body.InnerHTML = strOncekiIcerik then
           begin
           boolDongudenCik := True;
           Durum           :=True;
           Form1.StatusBar1.Panels[0].Text:='Yüklendi';/// Dileyen bunu silebilir..
           end else strOncekiIcerik := Form1.WebBrowser1.OleObject.Document.Body.InnerHTML;
  end;
     Result:=Durum;
end;



Kullanım şekli

Kod: Tümünü seç


 IF ( Sayfa_yuklendimi('http://www.birebin.com')= true) AND ( Pos( 'Sayfa içinde aranacak kelime', Form1.WebBrowser1.OleObject.Document.Body.InnerHTML ) > 0) then 
begin
//// sayfa yüklenip , sayfa içinde aradığımız bir sabit varsa işlemleri yap diyoruz..
  Showmessage('yüklendi');
end else showmessage('yüklenmedi');
Lord_Ares
Üye
Mesajlar: 1070
Kayıt: 15 Eki 2006 04:33
Konum: Çorlu

Re: READYSTATE_COMPLETE bir defa çok gerçekleşiyorsa

Mesaj gönderen Lord_Ares »

Mrman hocam peki Form1.WebBrowser1.ReadyState <> READYSTATE_COMPLETE complate olmuyorsa programımız sürekli uykuda kalıyor bu tür bir durumda ne yapmalıyız.
Downloada complate ve documan complate kısımlarında pos ile sonuca ulaşmayı denedim fakat bu işlemlerde bir kez gerçekleşmediği için düzgün sonuca ulaşamadım.
Aradığım değer var olana kadar web sayfasının içeriğini al dediğimde de read state olayından farkı kalmadı değer gelmeyince sürekli dondu..
Teşekkürler
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: READYSTATE_COMPLETE bir defa çok gerçekleşiyorsa

Mesaj gönderen mrmarman »

Lord_Ares yazdı:Mrman hocam peki Form1.WebBrowser1.ReadyState <> READYSTATE_COMPLETE complate olmuyorsa programımız sürekli uykuda kalıyor bu tür bir durumda ne yapmalıyız.
Downloada complate ve documan complate kısımlarında pos ile sonuca ulaşmayı denedim fakat bu işlemlerde bir kez gerçekleşmediği için düzgün sonuca ulaşamadım.
Aradığım değer var olana kadar web sayfasının içeriğini al dediğimde de read state olayından farkı kalmadı değer gelmeyince sürekli dondu..
Teşekkürler
iki aşamalı bir çözüm önericem...İlki vardır ya da yoktur önemli değil. Aslında ikinci aşama senin çözümün olacaktır.
(1) İlk olarak sisteminde mallware vs. vardır, explorer sürekli birine takılı kalmıştır.

(2) ilk bloğu (WHILE ... READY_STATE olayı) artık kullanmayabilirsin. Sadece InnerHTML değişikliği / farkına bakılarak işlemin bittiği kanaatine varabilirsin. Çıkar çıkmaz da WebBrowser1.STOP komutu ile suspend olma durumunu ortadan kaldırabilirsin.
Resim
Resim ....Resim
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: READYSTATE_COMPLETE bir defa çok gerçekleşiyorsa

Mesaj gönderen mrmarman »

Ayrıca bir ön kontrol yapılması şart gelir onu da bu başlığı okuyanlar için hatırlatayım...

USES satırına MSHTML ekleyip aşağıdaki şekilde bir ön kontrol yapılırsa, henüz navigate edilmemiş, tamamlanmamış olma durumunu yani NIL olma durumunu yakalayıp hataya düşmesini engellemiş olursunuz. :idea:

Kod: Tümünü seç

    if Assigned( WebBrowser1.Document ) AND Assigned ( (((WebBrowser1.Document) as IHTMLDocument2).body as IHTMLElement2))
Resim
Resim ....Resim
Lord_Ares
Üye
Mesajlar: 1070
Kayıt: 15 Eki 2006 04:33
Konum: Çorlu

Re: READYSTATE_COMPLETE bir defa çok gerçekleşiyorsa

Mesaj gönderen Lord_Ares »

teşekkürler hocam deneyip çözüm bulmaya çalışacağım..
Cevapla