有很多使用 Selenium Python 處理 shadow DOM 的例子。我想在 Perl 中做同樣的事情。
Perl 的 Selenium::Remote::Driver 沒有影子 DOM 支持,但我應該可以通過 JavaScript 做到這一點。我的靈感來自于 access-shadow-dom-tree-with-selenium。
以下是我在 Perl 中的代碼
#!/usr/bin/env perl
use Selenium::Chrome;
my $driver = Selenium::Chrome->new (
startup_timeout => 60,
custom_args => "--log-path=/tmp/selenium_chromedriver",
logfile => "/tmp/selenium_chromedriver2",
debug_on => 1,
extra_capabilities => {
'goog:chromeOptions' => {
args => [
'--no-sandbox',
'--disable-dev-shm-usage',
'--window-size=1260,720',
'--user-data-dir=/tmp/selenium_chrome',
],
},
},
);
$driver->get("chrome-search://local-ntp/local-ntp.html"); # chrome new tab
my $shadow_host = $driver->find_element("html/body/ntp-app", "xpath");
my $shadow_root = $driver->execute_script('return arguments[0].shadowRoot', $shadow_host);
for my $e ( @{$shadow_root->find_elements(':host > *', 'css')} ) {
# error: Can't call method "find_elements" on unblessed reference
print "found\n";
}
$driver->shutdown_binary();
但我得到了錯誤:Can't call method "find_elements" on unblessed reference。
我該如何克服這個錯誤?
感謝您的任何幫助。
- 我的環境是:ubuntu 18、Perl 5.26、Selenium:Chrome 1.46、Chrome 99、chromedriver 99。
- 使用 Python 3.8.5 測驗了相同的機制。
- 為什么我不使用 Python?因為我作業場所的服務器只有 Perl,沒有 Python 3。
uj5u.com熱心網友回復:
以下代碼有效
#!/usr/bin/env perl
use Selenium::Chrome;
my $driver = Selenium::Chrome->new (
startup_timeout => 60,
custom_args => "--log-path=/tmp/selenium_chromedriver",
logfile => "/tmp/selenium_chromedriver2",
debug_on => 1,
extra_capabilities => {
'goog:chromeOptions' => {
args => [
'--no-sandbox',
'--disable-dev-shm-usage',
'--window-size=1260,720',
'--user-data-dir=/tmp/selenium_chrome',
],
},
},
);
$driver->get("chrome-search://local-ntp/local-ntp.html"); # chrome new tab
my $shadow_host = $driver->find_element("html/body/ntp-app", "xpath");
package MyShadow {
sub new {
my ($class, %attrs) = @_;
my $shadow_root = $attrs{driver}->execute_script('return arguments[0].shadowRoot', $attrs{shadow_host});
return undef if ! $shadow_root;
$attrs{shadow_root} = $shadow_root;
bless \%attrs, $class;
}
sub find_element {
my ($self, $target, $scheme) = @_;
die "scheme=$scheme is not supported. Only css is supported" if $scheme ne 'css';
return $self->{driver}->execute_script(
"return arguments[0].querySelector(arguments[1])",
$self->{shadow_root},
$target
);
}
sub find_elements {
my ($self, $target, $scheme) = @_;
die "scheme=$scheme is not supported. Only css is supported" if $scheme ne 'css';
return $self->{driver}->execute_script(
"return arguments[0].querySelectorAll(arguments[1])",
$self->{shadow_root},
$target
);
}
};
my $shadow_driver = MyShadow->new(driver=>$driver, shadow_host=>$shadow_host);
if ($shadow_driver) {
for my $e ( @{$shadow_driver->find_elements(':host > *', 'css')} ) {
print "found\n";
}
}
$driver->shutdown_binary();
關鍵點:
對于 Selenium,無論是 Python 還是 Perl,它們都是 javascript 的包裝器。只要你得到正確的 javascript,你就可以做任何你想做的事情。
對于 Shadow 驅動程式,您只需要實作 find_element() 和 find_elements()。
我只實作了“css”,沒有實作“xpath”,因為這就是 Python 在 2022 年 9 月 19 日所做的事情。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/513204.html
