如何从 perl 中转义 selenium 中没有的元素?
How can I escape an element not found in selenium from perl?
我正在编写一段代码,我可以在其中访问一个网站,其中一些元素由一些 ID 定义。根据某些参数,此元素具有不同的 ID。
例如我有一张蓝色的网和一张红色的网。都具有相同的元素,但其中一个的 id 是 "title_red",另一个是 "title_blue".
我可以"solve"这个,通过这样的代码:
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" 程序将在未获取元素后崩溃。使用它,它可以解决问题,但它仍然会生成一个打印异常,当我查看页面中不存在的许多元素并且很难看到页面中的其余打印时,这非常烦人控制台。这是错误:
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 70) line 70.
有没有办法检查该元素是否存在或只是隐藏此打印件?我已经尝试了一些 "no warnings" 个例子,但我什么都做不了,我认为这不是警告,而是错误。如果我在 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 或 class 可能因地区而异,我被重定向到 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_variable\n";
$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_variable\n";
$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_variable\n";
$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_variable\n";
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:
根据当前代码块和粗略的所有修订,您需要将 $itle
更改为 $title 并可能将 $titleeq
更改为 $title eq 如下:
使用Selenium::Waiterqw/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;
}
我找到了一个 "solution",它既不简洁也不简短,但可以完成工作,它使用 find_elements 而不是 find_element。这 returns 一个空数组,然后您可以检查它是否已定义。
我很想看到另一个解决方案,因为如果我必须检查很多元素,这会添加很多 "dirty" 代码。
示例:
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()};
我正在编写一段代码,我可以在其中访问一个网站,其中一些元素由一些 ID 定义。根据某些参数,此元素具有不同的 ID。
例如我有一张蓝色的网和一张红色的网。都具有相同的元素,但其中一个的 id 是 "title_red",另一个是 "title_blue".
我可以"solve"这个,通过这样的代码:
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" 程序将在未获取元素后崩溃。使用它,它可以解决问题,但它仍然会生成一个打印异常,当我查看页面中不存在的许多元素并且很难看到页面中的其余打印时,这非常烦人控制台。这是错误:
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 70) line 70.
有没有办法检查该元素是否存在或只是隐藏此打印件?我已经尝试了一些 "no warnings" 个例子,但我什么都做不了,我认为这不是警告,而是错误。如果我在 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 或 class 可能因地区而异,我被重定向到 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_variable\n";
$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_variable\n";
$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_variable\n";
$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_variable\n";
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:
根据当前代码块和粗略的所有修订,您需要将 $itle
更改为 $title 并可能将 $titleeq
更改为 $title eq 如下:
使用Selenium::Waiterqw/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;
}
我找到了一个 "solution",它既不简洁也不简短,但可以完成工作,它使用 find_elements 而不是 find_element。这 returns 一个空数组,然后您可以检查它是否已定义。
我很想看到另一个解决方案,因为如果我必须检查很多元素,这会添加很多 "dirty" 代码。
示例:
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()};