Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

OLE wrapper for IE

by rkg (Hermit)
on Sep 30, 2003 at 01:38 UTC ( [id://295161]=sourcecode: print w/replies, xml ) Need Help??
Category: Win32
Author/Contact Info rkg
Description: This code snippet gives some sense of how to use OLE to run MS Internet Explorer. It only handles a few functions. It is loosely based on http://samie.sourceforge.net/. For a fuller implementation, see http://samie.sourceforge.net/. Yes, usually you are better off using LWP or WWW::Mechanize, but sometimes OLE makes sense: see 294924 for thoughts on this issue.

package Win32::OLE::IE;

use strict;
use warnings;
use Win32::OLE qw(EVENTS);
use Time::HiRes qw(sleep);

sub new {
    my ($class, %args) = @_;
    my $self = {};
    bless $self, $class;
    $self->{IE} = Win32::OLE->new("InternetExplorer.Application") or d
+ie $!;
    my %defaults = (
        left      => 0,   top       => 0,
        height    => 400, width     => 700,
        menubar   => 1,   toolbar   => 1,
        statusbar => 1,   visible   => 1,
        %args
    );
    $self->{IE}->{$_} = $defaults{$_} foreach keys %defaults;
    $self->pause;
    return $self;
}

sub content {
    my ($self) = @_;
    my $doc = $self->{IE}->{Document};
    return $doc->{DocumentElement}->{InnerHTML}
      if defined($doc->{DocumentElement});
}

sub navigate {
    my ($self, $url) = @_;
    $self->{IE}->navigate($url);
    $self->pause();
}

sub messageloop {
    my ($self) = @_;
    Win32::OLE->MessageLoop();
}

sub pause {
    my ($self) = @_;
    while ($self->{IE}->{Busy} == 1) { sleep(0.2); }
}

sub DESTROY {
    my ($self) = @_;
    $self->{IE}->Quit();
}

sub setform {
    my ($self, $name, $value, $index) = @_;
    $index = 0 if !$index;
    my $cnt   = 0;
    my $doc   = $self->{IE}->{Document};
    my $forms = $doc->forms;
    for (my $i = 0 ; $i < $forms->length ; $i++) {
        my $form = $forms->item($i);
        for (my $j = 0 ; $j < $form->elements->all->length ; $j++) {
            my $elemname = $form->elements->all($j)->getAttribute("nam
+e");
            if ($elemname and $elemname eq $name) {
                if ($index == $cnt) {
                    $form->elements->all($j)->{value} = $value;
                    return;
                }
                else { $cnt++; }
            }
        }
    }
    die "could not find name=$name index=$index";
}

sub pushbutton {
    my ($self, $name, $index) = @_;
    $index = 0 if !$index;
    my $cnt   = 0;
    my $doc   = $self->{IE}->{Document};
    my $forms = $doc->forms;
    for (my $i = 0 ; $i < $forms->length ; $i++) {
        my $form = $forms->item($i);
        for (my $j = 0 ; $j < $form->elements->all->length ; $j++) {
            my $elemname = $form->elements->all($j)->getAttribute("nam
+e");
            my $elemtype = $form->elements->all($j)->getAttribute("typ
+e");
            if (    $elemname
                and $elemtype
                and $elemname eq $name
                and $elemtype eq 'submit')
            {
                if ($index == $cnt) {
                    $form->elements->all($j)->click;
                    $self->pause;
                    return;
                }
                else { $cnt++; }
            }
        }
    }
    die "could not find name=$name index=$index";
}

sub clicklink {
    my ($self, $name, $index) = @_;
    $index = 0 if !$index;
    my $cnt = 0;
    my $doc = $self->{IE}->{Document};
    for (my $i = 0 ; $i < $doc->all->length ; $i++) {
        if ($doc->all($i)->tagName =~ /^A$/) {
            my $text = $doc->all($i)->innerText;
            if ($text and $text =~ /\s*\Q$name\E\s*$/) {
                if ($index == $cnt) {
                    $doc->all($i)->click();
                    $doc->all($i)->fireEvent("onclick");
                    $self->pause;
                    return;
                }
                else { $cnt++; }
            }
        }
    }
    die "could not find name=$name index=$index";
}

1;

__DATA__

=head1 NAME

OLE::IE - Perl extension for automating Internet Explorer

=head1 SYNOPSIS

  use OLE::IE;
  my $ie = Win32::OLE::IE->new;
  $ie->navigate("http://www.google.com");
  my $html = $ie->content;
  $ie->setform('q','university of massachusetts', 0);
  $ie->pushbutton('btnG', 0);
  $ie->clicklink('Advanced Search',0);

=head1 DESCRIPTION

An OLE wrapper for Internet Explorer, loosely based on
Win32::SAM.

=head1 SEE ALSO

Win32::SAM
Replies are listed 'Best First'.
Re: OLE wrapper for IE
by Anonymous Monk on Sep 26, 2004 at 23:41 UTC

    OK, I have to say, You freekin' rule!

    Thank you for this posting.

    I recently ran into a situtation with !@#($*%! *.jsp pages that perplexed me. (they were https so I couldn't even sniff the 'real' url strings,... )I could not retrieve a '3rd {post, i think} level deep in' of jsp pages with ANY 'text-based' system. None of LWP, wget, lynx, links (all with SSL support) would work but i could retrieve the pages with any GUI browser, yes, the exact url failing with LWP pasted into 'any' browser window worked!? I think it has something to do with javabean sessions or something, (it's not cookies or javascript problem, but i'm no java programmer).

    So anyway I had to do a 'yukk crude hack - non-cross platform' with retrieving said pages with IE, I was having a hell of a time trying to get Document->DocumentElement->InnerHTML to work, for some reason and then i found your above code. Thanks for taking the time to post this!!!!

    maybe it doesn't have too big an audience but you should put this on cpan, it's handy for some situations where maybe nothing else well work.

    I realize this is old, and you may have moved on to doing other stuff but i had to take the time to say thanks

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://295161]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (8)
As of 2024-03-28 15:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found