Jump to content

Wait until string is found in HTML?


4b0082
 Share

Go to solution Solved by SmOke_N,

Recommended Posts

How can I write this so it stops spitting out "1" even when the string hasn't loaded yet? The page I'm trying to work with loads Javascript after the window is finished loading, which means the page isn't completely loaded even when it says it is.
 

Do
      Local $qData = _IEDocReadHTML("http://website.com")
      $load = StringRegExp($qData, '(?sU)Server Update', 3)
   Until $load = 1
Link to comment
Share on other sites

Have you tried using

_INetGetSource
Could be worth a try.

Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Link to comment
Share on other sites

This is a piece of code that I use. This may help.

#include <INet.au3>

Local $Source = _INetGetSource("http://forum.powweb.com/online.php?who=members")

If StringInStr($Source, "Welcome back,")                          = 0 Then MsgBox(48 + 4096, "Oh No!!", "Can't even read the page!", 2) ;If text doesn't exist
If StringInStr($Source, "The server is too busy at the moment.") <> 0 Then MsgBox(48 + 4096, "Oh No!!", "Busy server.", 2)              ;If text does exist

- Bruce /*somdcomputerguy */  If you change the way you look at things, the things you look at change.

Link to comment
Share on other sites

Oh, I just realized I had my flag set to creating an array "3" instead of the default "0" setting. It didn't seem to make a difference in _IEDocReadHTML but it works when I used Inet the right way. I'd still be interested in knowing why _IEDocReadHTML won't output properly, if anyone knows.

Link to comment
Share on other sites

This function returns the document source after any client-side modifications (e.g. by AutoIt or by client-side JavaScript).
It may therefore be different than what is shown by the browser View Source or by _INetGetSource().

:)

Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Link to comment
Share on other sites

Update: I thought that this would work to suit my needs, but unfortunately it doesn't. Turns out what I'm doing is considered a "client side" action, so I need _IEDocReadHTML to work with my script. What I'm doing is sorting a list in descending order by name and it takes a few seconds after the page loads for the javascript to automatically update the list from unsorted to sorted. My trigger is when the list hits sorted based on a specific line in the updated HTML (changes do not show in the source code, only on "inspect elements").

I feel like this code is working, but I'm trying to pull information from a new tab opened through $oIE.Navigate.

Is there a way to get $oIE.Navigate("http://site.com") to function with _IELoadWait? Here's my code..


 

Local $oIE = _IECreate($url[0], 0, 1, 0)

   For $cPage = 1 to $tPage-1
      Sleep(750)
      $oIE.Navigate($url[$cPage], 0x0800)
   Next

; Successfully opens the full $url array into new tabs, no problems here.

   For $cPage = 0 to $tPage-1
      $tab[$cPage] = _IEAttach($url[$cPage], "url")
   Next

; Successfuly assigns each tab to a new variable, no problems here (I think.)

   _IELoadWait($tab[$tPage-1]) ; This bascially says "wait for the last opened tab to load", but it's not working..

   Do
      Local $qData = _IEDocReadHTML($tab[$tPage-1])
      $load = StringRegExp($qData, 'SORT.*point" style="d')
   Until $load <> 0

; Page won't wait for load!!
Edited by 4b0082
Link to comment
Share on other sites

  • Moderators

; you think?
   For $cPage = 0 to $tPage-1
      $tab[$cPage] = _IEAttach($url[$cPage], "url")
      ConsoleWrite("$tab[" & $cPage & "] is an object: " & (IsObj($tab[$cPage]) = True) & @CRLF)
   Next

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

I'm pretty sure I provided a much safer routine yesterday for this???

Edit: I added a Sleep before my IEAttach and they all output true, thanks for the debug.

I'm not sure what "safer routine" you're referring to, but I did what I could with what was on the link you gave me. If there's a better way to do it I'd like to know, I'm still learning.

$tab[0] is an object: True
$tab[1] is an object: True
$tab[2] is an object: True
$tab[3] is an object: True
$tab[4] is an object: True
Edited by 4b0082
Link to comment
Share on other sites

At this point, you'll need to check for something on the page that only happens when you have determined it is 'completely loaded', like a header or certain string.

Edited by MikahS

Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Link to comment
Share on other sites

  • Moderators

I pointed you to my code, you chose to use the OP's code that isn't safe (as I tried to point out to that OP, but they'll learn as you did).

Try this (keep in mind, I have no idea what you've declared or what you're doing really, this is pseudo code only):

#include <IE.au3>

Local $oIE = _IECreate($url[0], 0, 1, 0)
Local $a_temp
   For $cPage = 1 to $tPage-1
      $oIE.Navigate($url[$cPage], 0x0800)
      $a_temp = __IE_TabLoadWait($oIE, $url[$cPage], "url") ; much safer
      If Not @error Then $tab[$cPage] = $a_temp[1]
   Next

   Do
      Local $qData = _IEBodyReadHTML($tab[$tPage-1]) ; i assume it's in the body?
      $load = StringRegExp($qData, 'SORT.*point" style="d') ; no idea if this works
   Until $load <> 0


; this will return the objects of the tabs matching type/str and wait if need be
Func __IE_TabLoadWait(ByRef $o_obj, $s_str = "", $s_type = "", $n_msecexpire = 0)

    If Not IsObj($o_obj) Then
        Return SetError(1, 0, 0)
    EndIf

    Local $a_objret = 0
    Local $n_timer = TimerInit()

    While 1
        $a_objret = __IE_GetTabObjs($o_obj, $s_str, $s_type)
        If IsArray($a_objret) Then ExitLoop

        ; return if we set the wait timer and it's reached
        If $n_msecexpire > 0 Then
            If $n_timer >= $n_msecexpire Then
                Return SetError(2, 0, 0)
            EndIf
        EndIf
        Sleep(250)
    WEnd

    If Not IsArray($a_objret) Then
        Return SetError(3, 0, 0)
    EndIf
    
    ; set normal _ieloadwait default
    If $n_msecexpire < 1 Then $n_msecexpire = -1

    For $i = 1 To UBound($a_objret) -  1
        _IELoadWait($a_objret[$i], 0, $n_msecexpire)
    Next
    
    ; this could return multiple if there is more than 1 tab
    ;   with the same url/title for $s_type passed
    Return $a_objret
EndFunc

; returns all the instances of tabs matching type/str criteria
Func __IE_GetTabObjs(ByRef $o_obj, $s_str = "", $s_type = "")

    If Not IsObj($o_obj) Then
        Return SetError(1, 0, 0)
    EndIf

    Local $a_otabs[101], $i_add = 0, $i_next = 1, $o_ieattach
    $s_type = StringLower($s_type)

    While 1
        ; we start at instance 1 and enum as we find more instances
        $o_ieattach = _IEAttach($o_obj, "instance", $i_next + 1)
        If @error = $_IEStatus_NoMatch Or Not IsObj($o_ieattach) Then ExitLoop
        
        ; control array size
        If Mod($i_add + 1, 100) = $i_add Then
            ReDim $a_otabs[$i_add + 101]
        EndIf

        Switch StringLower($s_type)
            Case "url"
                If String(Execute("$o_ieattach.locationurl")) = $s_str Then
                    $i_add += 1
                    $a_otabs[$i_add] = $o_ieattach
                EndIf
            Case "title"
                If WinGetText(String(Execute("$o_ieattach.hwnd"))) = $s_str Then
                    $i_add += 1
                    $a_otabs[$i_add] = $o_ieattach
                EndIf
            Case Else
                $i_add += 1
                $a_otabs[$i_add] = $o_ieattach
        EndSwitch
        $i_next += 1
    WEnd

    If $i_add = 0 Then Return SetError(2, 0, 0)

    ReDim $a_otabs[$i_add + 1]
    $a_otabs[0] = $i_add

    Return $a_otabs
EndFunc

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Your code is waiting for pages to load but still not finding the string I'm looking for, which I don't understand because the string search works fine when it's in a standalone AU3 with _IECreate to test it.

I know you said my code is unstable, but is there really no better alternative to "_IELoadWait($tab[$tPage-1])" then having to include an entire new function? Your script is almost as long as my entire code. It's not really a problem but I've handwritten everything so I can hunt down exactly where changes need to be made, and importing another script just makes it more difficult to work with (like I said, I'm still learning).

Edited by 4b0082
Link to comment
Share on other sites

I found a solution, it's not great - but it works! I think. SmOke_N, could you tell me what problems I might run into using this script as an alternative?

For $cPage = 0 to $tPage-1
      $tab[$cPage] = _IEAttach($url[$cPage], "url")
      If Not (IsObj($tab[$cPage]) = True) Then
         Local $i = 0
         Do
            $tab[$cPage] = _IEAttach($url[$cPage], "url")
            Sleep(500);;; This will let us
            $i += 1 ;;;;; wait 5 seconds before giving up!
            ConsoleWrite($i & @CRLF)
         Until (IsObj($tab[$cPage]) = True) OR $i = 10 ; If the page loads or we've timed out, move on
      EndIf
      ConsoleWrite("$tab[" & $cPage & "] is an object: " & (IsObj($tab[$cPage]) = True) & @CRLF) ; Checking to see results
   Next
Edited by 4b0082
Link to comment
Share on other sites

That will give up in 5 seconds, as Sleep uses ms not seconds. 1000 ms = 1 second. So, 500 ms = .5 seconds. Just a tip ;)

Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Link to comment
Share on other sites

  • Moderators

Your code is waiting for pages to load but still not finding the string I'm looking for, which I don't understand because the string search works fine when it's in a standalone AU3 with _IECreate to test it.

I know you said my code is unstable, but is there really no better alternative to "_IELoadWait($tab[$tPage-1])" then having to include an entire new function? Your script is almost as long as my entire code. It's not really a problem but I've handwritten everything so I can hunt down exactly where changes need to be made, and importing another script just makes it more difficult to work with (like I said, I'm still learning).

Note my comments, I did change DocRead to BodyRead, maybe you'll need to revert back.

As far as my code as long as your script, they are two functions, if you look at the IE.au3 file you're including alone, you'll see your script is much longer than you think lol... you're only referring to visible code.

 

 

I found a solution, it's not great - but it works! I think. SmOke_N, could you tell me what problems I might run into using this script as an alternative?

For $cPage = 0 to $tPage-1
      $tab[$cPage] = _IEAttach($url[$cPage], "url")
      If Not (IsObj($tab[$cPage]) = True) Then
         Local $i = 0
         Do
            $tab[$cPage] = _IEAttach($url[$cPage], "url")
            Sleep(500);;; This will let us
            $i += 1 ;;;;; wait 5 seconds before giving up!
            ConsoleWrite($i & @CRLF)
         Until (IsObj($tab[$cPage]) = True) OR $i = 10 ; If the page loads or we've timed out, move on
      EndIf
      ConsoleWrite("$tab[" & $cPage & "] is an object: " & (IsObj($tab[$cPage]) = True) & @CRLF) ; Checking to see results
   Next

I'm not a fan of this _IEAttach method the way you are doing, I continuously point this out to everyone.

So I'm afraid I will have to dismiss myself from helping with those that wish to continue to use it in this manner.

Very best of luck to you.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

I know, $i counts to 10 so 500 x 10 = 5000ms. :)

Brain fart on my part! :geek:

Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Link to comment
Share on other sites

I'm not sure I actually understand _IEAttach to be honest, I read through your other post a bit and I think it sounds like _IEAttach has a problem with latching on to ANY instance it meets rather than a specific one, but I've read the docs and it still doesn't make complete sense about the proper and improper way to use it.

Could you give a short example of a right and wrong way to use it?

Link to comment
Share on other sites

  • Moderators
  • Solution

Let's say I have two separate IE windows open, without even keeping in mind that other applications could have IE instances open as well.

In the first, I only have:

http://autoitscript.com for the url and no other tabs

The second I have:

http://google.com for the url

And I have a tab:

http://autoitscript.com

If I use _IEAttach("http://autoitscript.com", "url"), which of the window objects am I grabbing the object instance from?

In addition, debug mode with that could be horrible too, you don't know how many times I forget to close the IE window I'm testing code in before running my code again!

IMO, the proper way to actually grab the "correct" instance of the tab would be to use _IEAttach() with instance, eg. _IEAttach("", "instance", number of tab I want starting from 0 (original page))  Then to match up either url/hwnd/title/innertext/etc.

That's what the code I provided does, it matches the instance, then it matches your criteria (url, title, or just return anything with a blank string for 3 param).  It's quick and dirty, but it works.

The reason I safeguard code like this, is because I know how fickle IE really is.  Doesn't matter what version.  If I'm going to do work in it, I need my code reliable at the very least, to not be the reason why something is failing.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...