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

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 6/27/06, Xavier Noria <fxn@hashref.com> wrote:

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

Bret

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

-- fxn

···

On Jun 28, 2006, at 0:27, bpettichord@gmail.com wrote:

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

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

···

On Jun 27, 2006, at 20:15, Justin Bailey 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.