IE> = 9时,Win32 :: IEAutomation不会点击链接

时间:2014-05-15 21:09:06

标签: perl web-scraping

在现代设置(Windows 7 64位,IE 11,ActiveState Perl 5.16 64位)上,Win32::IEAutomation(v0.5)中的Click方法似乎不起作用。这是一个例子,很少改编自文档:

use Win32::IEAutomation;
my $ie = Win32::IEAutomation->new( visible => 1);
$ie->gotoURL('http://www.google.com');
$ie->getLink('linktext:', "About")->Click;       

此时,我应该在IE中看到“关于”页面。但我仍然在IE中看到Google的主页,我无法使用Win32 :: IEAutomation中的Content方法获取“关于”页面的来源。

我在较旧的设置上遇到了同样的问题(Vista SP2 64位,IE 9,ActiveState Perl 5.10.1)。但是当我使用IE8而不是IE9的类似设置时,问题不会出现。因此问题似乎在于IE8和后续IE版本之间的差异。

我能做些什么来让示例脚本与更新版本的IE一起使用吗?

2 个答案:

答案 0 :(得分:1)

Win32::IEAutomationInternetExplorer.ApplicationMSHTML所展示的各种界面的薄包装。

因此,我尝试通过编写脚本来执行导航而不使用Win32::IEAutomation来复制问题。在链接上使用click方法未启动导航,而是将href传递给Navigate2

click方法" 通过导致HTMLFrameSiteEvents :: onclick事件触发来模拟点击,"意味着将涉及页面上定义的任何onClick处理程序。我不确定为什么没有启动专门的导航。

但是,问题并非针对Google的主页:我使用example.com进行了尝试,并且在该页面上的链接上调用click方法也未启动导航。

以下是我用作测试平台的脚本:

#!/usr/bin/env perl

use strict;
use warnings;
use feature 'say';

use Win32::OLE qw(EVENTS in valof);
$Win32::OLE::Warn = 3;

my $url = 'https://www.google.com/';

my %event_handler = (
    DocumentComplete => \&onDocumentComplete,
);

my %page_handler = (
    'https://www.google.com/'
        => \&onPageGoogleHome,
    'https://www.google.com/intl/en/about/'
        => \&onPageGoogleAbout,
);

my $ie = Win32::OLE->new(
    "InternetExplorer.Application", sub { $_[0]->Quit }
);

Win32::OLE->WithEvents($ie, \&Event, 'DWebBrowserEvents2');

$ie->{Visible} = 1;
$ie->Navigate2($url);

Win32::OLE->MessageLoop;
Win32::OLE->SpinMessageLoop;

$ie->Quit;

sub Event {
    my ($ie, $event, @argv) = @_;

    if (exists $event_handler{$event}) {
        $event_handler{$event}->($ie, \@argv);
    }
    else {
        # unhandled event
    }
    return;
}

sub onDocumentComplete {
    my ($ie, $argv) = @_;
    my $url = valof($argv->[-1]);
    if (exists $page_handler{$url}) {
        $page_handler{$url}->($ie, $argv);
    }
    else {
        # unhandled page
    }
    return;
}

sub onPageGoogleHome {
    my ($ie, $argv) = @_;
    say "We are on Google's home page";
    my $links = $ie->Document->links;
    my $about_link;
    for my $link (in $links) {
        if ($link->innerText eq 'About') {
            say "Found 'About' link";
            $about_link = $link;
            last;
        }
    }
    if ($about_link) {
        # Doesn't work:
        # $about_link->click;

        $ie->Navigate2($about_link->href);
    }
    return;
}

sub onPageGoogleAbout {
    my ($ie, $argv) = @_;
    say "Yay, we are on the about page!";
    Win32::OLE->QuitMessageLoop;
    return;
}

版本信息:

这是为MSWin32-x64多线程构建的perl 5,版本19,subversion 12(v5.19.12)

Internet Explorer 11

Windows 8.1 Pro 64位

答案 1 :(得分:1)

我在Strawberry Perl v5.18.2和Win32::IEAutomation v0.5以及IE v11.0.9600.17105中使用->Click()观察到同样的错误行为。

我的工作是直接使用gotoURL()方法。这显然不适用于javascript操作,但适用于此特定示例。

use strict;
use warnings;

use Win32::IEAutomation;

my $ie = Win32::IEAutomation->new( visible => 1);
$ie->gotoURL('http://www.google.com');

my $about = $ie->getLink('linktext:' => 'About')
    or die "Unable to find About";

# $about->Click(); # <--- does not work, using alternative method

$ie->gotoURL($about->linkUrl());