如何从 perl 中转义硒中找不到的元素?



我正在编写一个代码,我在其中访问一个网站,其中包含由某些ID定义的一些元素。 根据某些参数,此元素具有不同的id。

例如,我有一个蓝色的网和一个红色的网。它们都具有相同的元素,但一个中的 id 是"title_red",另一个是"title_blue"。

我可以通过这样的代码来"解决"这个问题:

use Selenium::Waiter qw/wait_until/;
my $title="";
wait_until{$itle=($driver->find_element("//span[contains(@id,'id_blue'))]")->get_text()}timeout => 1;
if ($titleeq ""){ #It'S not blue
wait_until{$title=($driver->find_element("//span[contains(@id,'id_red')]")>get_text()}timeout => 1;    
}

如果我不使用"wait_until",程序将在未获取元素后崩溃。使用它,它可以解决问题,但它仍然会生成一个打印异常,当我查看许多不在页面中的元素时,这非常烦人,并且很难在控制台中看到其余的打印。这是错误:

强制"id"失败:将对象传递给 WebElement id 属性时,它必须至少具有 ELEMENT 或 element-6066-11e4-a52e-4f735466cecf 键之一。 在 (评估 70) 第 70 行。

有没有办法检查元素是否存在或只是隐藏此打印?我尝试了一些"无警告"的例子,但我无法让任何东西工作,我认为这不是警告,这是一个错误。如果我在try/catch内尝试它,它将执行捕获。

我已经按照评论中的建议尝试了这个,但我仍然收到错误:

print "Here I check if it's fixed:n";
try{wait_until{$variable=($driver->find_element("//img[@class='".$other_variable."']"))}timeout=>1}catch{};

编辑:我只是写了一个代码来重现问题,而不仅仅是从我的代码中写几行。正确的 ID 或类可能会根据地区而变化,我被重定向到 google.de:

use Selenium::Chrome;
use Selenium::Remote::Driver;
use Selenium::Waiter qw/wait_until/;
use Try::Tiny;
use strict;
use warnings;
use utf8;
my $driver = Selenium::Chrome->new('binary' => "C:\chromedriver.exe"); 
my $login="http://google.com";
$driver->get($login); 
print "Let's try the wrong id:n";
my $print_variable ="";
my $id_not_found = "something";
wait_until{$print_variable=($driver->find_element("//div[@class='".$id_not_found."']"))->get_text()};  #this produces an error
print "Variable now is: $print_variablen";
$print_variable="";
print "Let's try the right id:n";
my $id_found = "_gIg";
wait_until{$print_variable=($driver->find_element("//div[@class='".$id_found."']"))->get_text()};  #this not
print "Variable now is: $print_variablen";
$print_variable="";
print "Let's try the wrong id with try, catch:n";
try{wait_until{$print_variable=($driver->find_element("//div[@class='".$id_not_found."']"))->get_text()}}catch{};  #this produces an error
print "Variable now is: $print_variablen";
$print_variable="";
print "Let's try the wrong id with try, catch and catch statement:n";
try{wait_until{$print_variable=($driver->find_element("//div[@class='".$id_not_found."']"))->get_text()}}catch{warn "ERROR: $_";}; #this produces an error
print "Variable now is: $print_variablen";
sleep(10);
$driver->shutdown_binary();

这是输出:

perl example_stack.pl
Let's try the wrong id:
coercion for "id" failed: When passing in an object to the WebElement id attribute, it must have at least one of the ELEMENT or element-6066-11e4-a52e-4f735466cecf keys. at (eval 66) line 70.
Variable now is:
Let's try the right id:
Variable now is: Hinweise zum Datenschutz bei Google
Let's try the wrong id with try, catch:
coercion for "id" failed: When passing in an object to the WebElement id attribute, it must have at least one of the ELEMENT or element-6066-11e4-a52e-4f735466cecf keys. at (eval 66) line 70.
Variable now is:
Let's try the wrong id with try, catch and catch statement:
coercion for "id" failed: When passing in an object to the WebElement id attribute, it must have at least one of the ELEMENT or element-6066-11e4-a52e-4f735466cecf keys. at (eval 66) line 70.
Variable now is:

我找到了一个"解决方案",它既不干净又简短,但可以完成工作,那就是使用find_elements而不是find_element。这将返回一个空数组,然后您可以检查它是否已定义。

我很想看到另一种解决方案,因为如果我必须检查很多元素,这会添加很多"脏"代码。

例:

my $element_text="";
my $myid = "asdasd";
wait_until{$element_text=($driver->find_elements("//span[contains(@id,'".$myid."')]"))[0]}timeout => 1;                    
if (!defined($element_text)){$element_text=""}else{$element_text=$element_text->get_text()};

根据当前的代码块和所有粗略的修订,您需要将$itle更改为$title,并可能$titleeq更改为$title等式,如下所示:

使用硒::服务员qw/wait_until/;

my $title="";
wait_until{$title=($driver->find_element("//span[contains(@id,'id_blue'))]")->get_text()}timeout => 1;
if ($title eq ""){ #It'S not blue
wait_until{$title=($driver->find_element("//span[contains(@id,'id_red')]")>get_text()}timeout => 1;    
}

最新更新