如何使用 Selenium 和 Python 或 Perl 查找活动元素的相邻元素

发布于 2025-01-20 19:59:42 字数 1728 浏览 0 评论 0原文

的反问题

$driver.get_element_by_xpath(....)

这是背景

我有一系列动态生成的页面需要解析。目标元素没有好的定位器、xpath、文本或 id。然而,相邻元素有一个唯一的文本来匹配。我的计划是找到相邻元素并使用其 xpath 得出目标 xpath。

$neighbor_element = $driver.get_element_by_text("unique text"); # or some other way
$neighbor_xpath = $neighbor_element.xpath; # this step is the question
$target_xpath = modify($neighbor_xpath); # this is my function
$target_element = $driver.get_element_by_xpath($target_xpath);

我四处搜寻过。找不到从元素、Perl 或 Python 获取 xpath 的函数或方法。


更新

我很抱歉无法发布示例页面,因为它属于一家公司,但我希望问题足够简单。 当我使用 chrome devtools 进行检查时,我看到 xpath 相关

neighbor xpath = //*[@id="lable_ni.dynmic_string 123456"]/lable/span[2]
target   xpath = //*[@id="dynmic_string 123456"]

Update2

这是虚拟测试文件

<!DOCTYPE html>
<html>

<head></head>

<body>
    <div>
        <div id="lable_ni.dynmic_string 123456">
            <label id="lable_ni.dynmic_string 123456">
                <!-- I use this as neighbour element -->
                <span>unique text</span>
            </label>
        </div>
        <div>
            <!-- target element is here -->
            <textarea id="dynmic_string 123456">target text is here</textarea>
        </div>
    </div>
</body>

</html>

这就是它的样子

在此处输入图像描述

我的策略是

  1. 找到“唯一文本”的 xpath。 (这个文本是事先知道的)
  2. 将其转换为目标文本的xpath
  3. 目标文本

得到我在第一步卡住的

This is a inverse question of

$driver.get_element_by_xpath(....)

Background

I have a series of dynamically generated pages to parse. The target element doesn't have a good locator, xpath, text, or id. However, the neighbor element has a unique text to match. My plan is to locate the neighbor element and use its xpath to come up with the target xpath.

$neighbor_element = $driver.get_element_by_text("unique text"); # or some other way
$neighbor_xpath = $neighbor_element.xpath; # this step is the question
$target_xpath = modify($neighbor_xpath); # this is my function
$target_element = $driver.get_element_by_xpath($target_xpath);

I have searched around. cannot find a function or method to get xpath from an element, Perl or Python.


Update

I apologize that I cannot post the example page because it is owned by a company, but I hope the question is straightforward enough.
When I use chrome devtools to inspect, I see the xpath are related

neighbor xpath = //*[@id="lable_ni.dynmic_string 123456"]/lable/span[2]
target   xpath = //*[@id="dynmic_string 123456"]

Update2

This the dummy test file

<!DOCTYPE html>
<html>

<head></head>

<body>
    <div>
        <div id="lable_ni.dynmic_string 123456">
            <label id="lable_ni.dynmic_string 123456">
                <!-- I use this as neighbour element -->
                <span>unique text</span>
            </label>
        </div>
        <div>
            <!-- target element is here -->
            <textarea id="dynmic_string 123456">target text is here</textarea>
        </div>
    </div>
</body>

</html>

This is how it looks like

enter image description here

My strategy was to

  1. find the xpath of "unique text". (this text is known beforehand)
  2. convert it to the xpath of target text
  3. get the target text

I stuck at the first step

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

第几種人 2025-01-27 19:59:42

找到该“已知邻居”的父级,然后找到其选择的子级,或者列表中已知邻居的下一个子级。

我对目标的了解有点困惑。原文是这么说的

目标元素没有好的定位器、xpath、文本或 id。

但编辑显示,

target xpath = //*[@id="dynmic_string 123456"]

既然必须有某种方式来告诉我,我将把它作为一个事实,即关于目标的某些信息是已知的。另一种方法是获取所有孩子(即所有兄弟姐妹)并浏览它们并找到已知孩子旁边的孩子。

这是一个使用 Perl 的示例。对于这个页面,将已知邻居视为带有一些文本的

,并找到作为同级

且具有一些文本的目标。其中给定的文本。 (相当于查找具有问题编辑中给出的 id 的兄弟姐妹。)

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

use Selenium::Chrome;

my $url_SO = q(https://stackoverflow.com/questions/71849162/)
    . q(how-to-find-the-neighbour-element-of-an-active-element-)
    . q(using-selenium-with-pytho);

my $drv = Selenium::Chrome->new( 'extra_capabilities' => 
    { 'goog:chromeOptions' => { args => [ 'headless' ] }}  );

$drv->get($url_SO);
say "\nPage title: ", $drv->get_title, "\n";

# Our "neighbor": <p> with text 'This is...'
# Get parent with: 'element-spec/..'
my $parent = eval { 
    $drv->find_element(
        '//p[text()="This is a inverse question of"]/..') };
if ($@) { die "Error on <p>'s parent: $@" }
say "known-<p>'s parent tag: ", $parent->get_tag_name;
say "known-<p>'s parent text:";
say '-'x50, "\n", $parent->get_text, "\n", '-'x50;

# Target: <p> with text that contains word 'searched'
my $tgt = eval { 
    $drv->find_child_element( 
        $parent, q(./p[contains(text(), 'searched')]) ) };    
if ($@) { die "find-child error: $@" }
say "target text: ", $tgt->get_text;

这符合预期。我无法真正发布与该问题更接近的匹配,因为没有给出太多内容。如果我误解目标的显示 id 是已知的,则使用 find_child_elements$parent 上,并沿着列表探测已知邻居。目标应该是之前或之后的目标(你最好知道是哪一个:)

如果目标实际上不是真正的兄弟姐妹,而是更进一步的上升者(而不是直接父母)的孩子,则 xpath 表达可以使用附加的 /../.. (等)向上层次结构。

这使用(无服务器)Selenium::Chrome,方法在Selenium::Remote::DriverSelenium::Remote::WebElement

(应该可以执行整个已知的操作element->parent->child 具有单个 XPath 表达式,或者甚至可能直接查找兄弟姐妹,一旦有时间我就会查找。)

Find the parent of that "known-neighbor" then their select child, or children that are next in the list to the known one.

I am a little confused by what is known about the target. The original text says that

The target element doesn't have a good locator, xpath, text, or id.

but the edit shows

target xpath = //*[@id="dynmic_string 123456"]

Since there's got to be some way to tell I'll take it as a fact that something is known about the target. Another way would be to get all children (so, all siblings) and browse through them and locate the ones next to the known one.

Here is an example with Perl. For this very page, take that known-neighbor to be a <p> with some text and find the target which is a sibling <p> and which has some given text in it. (As an equivalent of finding a sibling with that id given in the question's edit.)

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

use Selenium::Chrome;

my $url_SO = q(https://stackoverflow.com/questions/71849162/)
    . q(how-to-find-the-neighbour-element-of-an-active-element-)
    . q(using-selenium-with-pytho);

my $drv = Selenium::Chrome->new( 'extra_capabilities' => 
    { 'goog:chromeOptions' => { args => [ 'headless' ] }}  );

$drv->get($url_SO);
say "\nPage title: ", $drv->get_title, "\n";

# Our "neighbor": <p> with text 'This is...'
# Get parent with: 'element-spec/..'
my $parent = eval { 
    $drv->find_element(
        '//p[text()="This is a inverse question of"]/..') };
if ($@) { die "Error on <p>'s parent: $@" }
say "known-<p>'s parent tag: ", $parent->get_tag_name;
say "known-<p>'s parent text:";
say '-'x50, "\n", $parent->get_text, "\n", '-'x50;

# Target: <p> with text that contains word 'searched'
my $tgt = eval { 
    $drv->find_child_element( 
        $parent, q(./p[contains(text(), 'searched')]) ) };    
if ($@) { die "find-child error: $@" }
say "target text: ", $tgt->get_text;

This does as expected. I can't really post a closer match to the question because not much is given. If I misunderstood that that shown id of the target is known then use find_child_elements on the $parent and go down the list probing for the known neighbor. The target should be the one before or after (and you better know which :)

If the target isn't in fact a true sibling, but is rather a child of a further ascendant (than the immediate parent), the xpath expressoin can go up the hierarchy with the additional /../.. (etc).

This uses the (server-less) Selenium::Chrome, with methods in Selenium::Remote::Driver and Selenium::Remote::WebElement

(It should be possible to do the whole known-element->parent->child thing with a single XPath expression, or perhaps even look directly for siblings, I'll look once there's time.)

浅唱ヾ落雨殇 2025-01-27 19:59:42

使用 selenium python客户端 incase,您可以将邻居元素定位为:

neighbor_element = driver.find_element(By.XPATH, "unique text")

取决于目标元素相对于 neighbornign_element 的位置使用以下任何一个 定位策略

  • INCASE target_element 是a &lt; span&gt; 元素,位于 左> emign> neighborign_element

      target_element = driver.find_element(locate_with(by.tag_name,“ span”)。to_left_of(nekine_element))
     

您必须包括以下导入:

from selenium.webdriver.support.relative_locator import locate_with

Using Selenium Python clients incase you are able to locate the neighbor element as:

neighbor_element = driver.find_element(By.XPATH, "unique text")

Depending upon the location of the target element with respect to neighbor_element you can use either of the following locator strategies:

  • Incase the target_element is a <span> element located left to the neighbor_element:

    target_element = driver.find_element(locate_with(By.TAG_NAME, "span").to_left_of(neighbor_element))
    

You have to include the following imports:

from selenium.webdriver.support.relative_locator import locate_with
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文