繁体   English   中英

有没有办法反向查找元素的XPath usig selenium

[英]Is there a way to reverse look up element's XPath usig selenium

许多听起来很愚蠢,但我需要在通过 Selenium 找到元素后知道它的 XPath。 原因是当我查找该元素时,我使用了文本搜索,因此,我不知道确切的 XPath,我可以用它来获取上述元素的兄弟元素。 即使它不是使用 Selenium,如果有一种方法可以间接地通过 BeautifulSoup 实现这一点,那就太好了。

我的程序的当前输出是这样的:

(Pdb) browser.find_elements_by_xpath('//*[contains(text(), "5StarMAX")]')

[<selenium.webdriver.remote.webelement.WebElement (session="8994add1f6f087a917bbb33f69f15f7c", element="7bad823c-1f3
e-445b-9a47-6d934fcacb8a")>, <selenium.webdriver.remote.webelement.WebElement (session="8994add1f6f087a917bbb33f69f1
5f7c", element="551df9b7-d2cb-4021-bb30-a2723c835adf")>, <selenium.webdriver.remote.webelement.WebElement (session="
8994add1f6f087a917bbb33f69f15f7c", element="b864c44b-8220-4010-843c-fbf0cfa1ba13")>, <selenium.webdriver.remote.webe
lement.WebElement (session="8994add1f6f087a917bbb33f69f15f7c", element="59d9f40d-d318-4e0d-9ab1-aa9df42d037c")>, <se
lenium.webdriver.remote.webelement.WebElement (session="8994add1f6f087a917bbb33f69f15f7c", element="260795bd-e7c6-43
b1-a8f0-10b36eb69787")>, <selenium.webdriver.remote.webelement.WebElement (session="8994add1f6f087a917bbb33f69f15f7c
", element="4e46be00-4578-4741-adc9-a5b6fc67a3e9")>, <selenium.webdriver.remote.webelement.WebElement (session="8994
add1f6f087a917bbb33f69f15f7c", element="df66abcb-bd99-4670-af07-404c085afb28")>]

如您所见,我找到了该元素,但我想以编程方式(使用 Python)搜索其兄弟元素。 没有办法——至少我知道(在尝试使用页面上随处可见的开发者工具找到它之后)——知道元素本身的 XPath。

尝试一起使用BeautifulSoupSelenium

您可以使用xpath_soup()尝试此解决方案

选项-A

import re
import itertools
from bs4 import BeautifulSoup
html = '<html><body><div><p>Hello World</p></div></body></html>'
soup = BeautifulSoup(html, 'lxml')
elem = soup.find(string=re.compile('Hello World'))
xpath_soup(elem)

输出

'/html/body/div/p'

选项-B

as-is引用。 您可能需要在这里和那里更改一些内容才能使其适合您。 来源

import re, itertools
from selenium import webdriver
from bs4 import BeautifulSoup as BS

def xpath_soup(element):
    components = []
    child = element if element.name else element.parent
    for parent in child.parents:
        siblings = parent.find_all(child.name, recursive=False)
        components.append(
            child.name
            if siblings == [child] else
            '%s[%d]' % (child.name, 1 + siblings.index(child))
            )
        child = parent
    components.reverse()
    return '/%s' % '/'.join(components)

def main():
    driver = webdriver.PhantomJS(executable_path='phantomjs.exe')
    driver.set_window_size(1400,1000)
    driver.get("https://www.pinterest.com/search/pins/?q=old")

    buttons = driver.find_elements_by_xpath('//button[@data-test-id="seemoretoggle"]');
    for btn in buttons:
        btn.click()

    html = driver.page_source
    soup = BS(html, 'html.parser')
    elem = soup.find(string=re.compile('Tiny House interior'))
    print(elem)
    xpath_soup(elem)
    print(xpath_soup(elem))

if __name__ == '__main__':
    main()

检查这些:

  1. https://qxf2.com/blog/auto-generate-xpaths-using-python/
  2. https://gist.github.com/ergoithz/6cf043e3fdedd1b94fcf

一旦找到它,就不需要父元素的 XPath。 您可以链接.find_element_*()调用。 例如,下面的代码将查找包含文本“5StarMAX”的元素,然后第二个 find 调用查找第一个元素的子 DIV。

请注意,第二个 XPath 以. . 这意味着在开始的第一个元素,搜索element

element = browser.find_element_by_xpath('//*[contains(text(), "5StarMAX")]')
element.find_element_by_xpath('./div')

如果它有帮助......使用单个 XPath 来表示组合两个发现看起来像

//*[contains(text(), "5StarMAX")]/div

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM