http://qs1969.pair.com?node_id=636644

Ad Aspera has asked for the wisdom of the Perl Monks concerning the following question:

Exalted Perl Monk Wizards: Goal: Navigate to a website using Win32::OLE, and save the results as a Web Archive - .MHT file in a directory and file name I choose programmatically, without prompting the user. The sample code below does not do the job. I am wondering what the proper mechanics are to accomplish this with Perl and the existing CPAN libraries
use Win32::OLE 'EVENTS'; use File::Spec::Functions; use File::Basename; $Win32::OLE::Warn = 3; $URL = "http://www.weather.com"; my $IE = Win32::OLE->new("InternetExplorer.Application") || die "Could not start Internet Explorer\n"; $IE->{Addressbar} = 1; $IE->{Menubar} = 1; $IE->{Toolbar} = 1; $IE->{Statusbar} = 1; $IE->{Width} = 800; $IE->{Height} = 700; $IE->{Top} = 0; $IE->{Left} = 0; $IE->{Resizable} = 1; $IE->{visible} = 1; # Navigate to desired URL $IE->Navigate($URL); while ($IE->{Busy}) { Win32::Sleep 500; Win32::OLE->SpinMessageLoop(); } $Contents = $IE->{DOCUMENT}; $Target = "g:\\zbuzz\\Weather.mht"; # # remove any prior file # $path = $Target; (my $filename = $path) =~ s/^.*[\\\/]//; # get just the filename po +rtion of path print "file=$filename\n"; $Targetdir= dirname($path); $currdir = Win32::GetCwd(); print "Current Working Directory=$currdir\n"; print "Targetdir=$Targetdir\n"; chdir ($Targetdir); $path = $Targetdir . "\\" . $filename; ($name, $dir, $ext ) = fileparse ($path, '\..*' ); print "name=$name, dir=$dir, ext=$ext \n"; $base = basename($path); $dir= dirname($path); print "dir=$dir, base=$base\n" ; # # changes the location of the saved file to the desired drive and dire +ctory # $newdir = chdir ( $dir); Win32::SetCwd($newdir); # moves the file save to g:\zbuzz unlink ( $Target ); # # Save the MHT file using ExecWB # my $OLECMDID_SAVEAS = '4'; my $OLECMDEXECOPT_PROMPTUSER = '0'; my $OLECMDEXECOPT_DONTPROMPTUSER = '1'; # prompts for the Save As +dialog # 4 - 1 combination produces Save Webpage ( so you can save as MHT ) # 4 - 1 combination populates file name as Window Title # 4 - 1 combination does not save the file in the desired directory; # 4 - 1 comination => have to manually change the directory to the des +ired location # # ExecWB does pull up the Save As HTML dialog box, however, Don't Prom +pt User does not work # $IE->ExecWB('4', '1', $Contents, $Target ); $IE->Quit(); exit; P.S., Where do I find the various constants to incorporate such as OLE +CMDEXECOPT_DONTPROMPTUSER, etc.

Replies are listed 'Best First'.
Re: Perl - ExecWB - SaveAs No Prompts
by harryC (Sexton) on Sep 14, 2007 at 13:56 UTC
    Hi
    look at http://support.microsoft.com/kb/244757
    URLDownloadToFile seems to be the way to go
    rgds
    harry
Re: Perl - ExecWB - SaveAs No Prompts
by harryC (Sexton) on Sep 14, 2007 at 12:18 UTC
    Hi
    Did you find a solution ?
    I am looking at the same problem but i only want to save as txt file
    I see that you are making a sleep to wait until the website has loaded
    I found some code at http://www.perl.com/pub/a/2005/04/21/win32ole.html
    that uses a check on event DocumentComplete to see if the website is complete
    #!/usr/bin/pe rl # find expl on http://www.perl.com/pub/a/2005/04/21/win32ole.html use Win32::OLE qw(EVENTS); my $URL = "http://samie.sf.net/simpleform.html"; my $IE = Win32::OLE->new("InternetExplorer.Application") || die "Could not start Internet Explorer.Application\n"; Win32::OLE->WithEvents($IE,\&Event,"DWebBrowserEvents2"); $IE->{visible} = 1; $IE->Navigate($URL); Win32::OLE->MessageLoop(); SetEditBox("name","samie"); sub Event { my ($Obj,$Event,@Args) = @_; print "Here is the Event: $Event\n"; if ($Event eq "DocumentComplete") { $IEObject = shift @Args; print "Here is my reference: $IEObject\n"; print "URL: " . $IEObject->Document->URL . "\n"; Win32::OLE->QuitMessageLoop(); } } sub SetEditBox { my ($name, $value) = @_; my $IEDocument = $IEObject->{Document}; my $forms = $IEDocument->forms; for (my $i = 0; $i < $forms->length; $i++) { my $form = $forms->item($i); if (defined($form->elements($name))) { $form->elements($name)->{value} = $value; } return; } }
    if you find the solution pls send me msg
    if i find it i will keep you up to date
    rgds
    Harry

      I found this old post when I had a similar issue. I could not find any combination that would save the page without user input, however for my purposes it was enough to save the HTML in the body. This can be done with:

      $IE->Navigate($root_url.$fname.$end_url); while ($IE->{Busy}) { Win32::Sleep 500; Win32::OLE->SpinMessageLoop(); } my $content = $IE->Document()->body()->innerHTML(); my $fh = IO::File->new(">>$save_dir/$fname.htm"); print $fh $content; $fh->close();

      Just thought I would add this as a note in case anyone else gets here

      my $htmlcontent = $IEObject->Document->body->innerhtml ; print $htmlcontent; Then you get the html content and can print it, or whatever you fancy