How to wrap methods of WIN32OLE objects

I am doing screen-scraping with Explorer:

WIN32OLE.new(‘InternetExplorer.Application’)

When you ask explorer to send some request and the method returns it
may need yet some time to complete building the DOM etc., and you
need to do something like:

def wait_for_completion
sleep 1 while @ie.busy
sleep 1 while @ie.readyState != 4
sleep 1 while @ie.document.readyState != ‘complete’
end

Since there is no class to subclass I tried to wrap the method to
submit simple requests (Navigate) like this:

untested

original_navigate = @ie.method(:Navigate)
def @ie.navigate(url)
original_navigate(url)
wait_for_completion
end

but it turns out that @ie is an object of class WIN32OLE that has
no :Navigate method (so the program dies in that @ie.method
(:Navigate)). Perhaps this has something to do with late binding. Do
you know any way to do that?

– fxn

Navigate is not a method. Instead it is handled by method_missing which
converts it to @ie.invoke(“Navigate”). Late binding, indeed.

Bret

On 6/27/06, Xavier N. [email protected] wrote:

I am doing screen-scraping with Explorer:

Have you looked at the WATIR project (http://wtr.rubyforge.org/)? It’s
intended as a way to test web applications on the client-side but it
also
scripts Internet Explorer very nicely. I bet it will even give you
access to
the DOM (plus a whole lot more). Sorry to not answer your question
directly,
but you may want to explore it and determine if you are reinventing the
wheel.

but it turns out that @ie is an object of class WIN32OLE that has

no :Navigate method (so the program dies in that @ie.method
(:Navigate)). Perhaps this has something to do with late binding. Do
you know any way to do that?

To address your code specifically, you can add methods to any object
this
way:

Add a method to @ie object. Untested!

class << @ie
def nav_and_wait(url)
@ie.Navigate(…)
wait_for_completion
end
end

Because of the way those COM objects are built, you may have to add this
method to each instance returned from WIN32OLE.new but that’s not too
hard
to do either. Note that I’m not overridding Navigate - I’m just adding a
new
method that wraps the call.

Justin

On Jun 28, 2006, at 0:27, [email protected] wrote:

Navigate is not a method. Instead it is handled by method_missing
which
converts it to @ie.invoke(“Navigate”). Late binding, indeed.

Ah, thank you, now I see how it works.

– fxn

On Jun 27, 2006, at 20:15, Justin B. wrote:

Have you looked at the WATIR project (http://wtr.rubyforge.org/)? It’s
intended as a way to test web applications on the client-side but
it also
scripts Internet Explorer very nicely. I bet it will even give you
access to
the DOM (plus a whole lot more). Sorry to not answer your question
directly,
but you may want to explore it and determine if you are reinventing
the
wheel.

Oh great! I will base the project on this instead of using the raw
object, they have already passed through the troubles I’ll discover :-).

– fxn