SeleniumPython-xpath包含一个同级问题



我正在尝试使用python-selenium在网页上选择用户,并打开他们个人资料的链接。以下是网页上每个用户的重复HTML:

<div class="w-50-ns w-100 ph1">
<div class="w-100 br1 pointer bg-animate hover-bg-dark-primary bg-near-black" onclick="openLink(event, '/users/0000')">
<div class="pv2 pr3 pl2 mb2 br1">
<div class="flex items-center pa1">
<div class="flex-auto mw-100">
<div class="flex items-center">
<div class="flex-none flex items-center">
<a class="relative overflow-hidden dib mr3-ns mr2 link" data-tippy-theme="lighter small" href="/users/0000" aria-expanded="false">
<img class="db ipp br1 object-cover" src="https://" width="70" height="70">
</a>
</div>
<div class="relative flex-auto mw-100 mw-none-ns" style="max-height: 58px; top: -1px;">
<div class="lh-copy truncate silver">
<a class="link span f5 fw7 secondary" href="/users/0000">UserName</a>
&nbsp;
<span class="f6 fw7 silver">AgeSex Category</span>
</div>
<div class="f6 lh-copy fw4 silver nowrap truncate">Los Angeles, California</div>
<div class="relative pd1 f6 fw4 lh-copy mid-gray nowrap truncate">
<a class="link gray hover-silver" href="/users/0000/pictures"># pics</a>
&nbsp;·&nbsp;
<a class="link gray hover-silver" href="/users/0000/posts"># posts</a>
</div>
</div>
</div>
</div>
<div class="flex">
<div class="tr">
</div>
</div>
</div>
</div>
</div>
</div>

这是我所关注的主要部分。我正在尝试检查AgeEx,即19F或20M,是否与选定的范围和性别匹配,如果匹配,请点击其上方的用户档案链接

<div class="lh-copy truncate silver">
<a class="link span f5 fw7 secondary" href="/users/0000">UserName</a>
&nbsp;
<span class="f6 fw7 silver">AgeSex Category</span>
</div>

我试过了:

self.driver.find_elements_by_xpath("//span[contains(., '18F') or contains(., '20M')])/preceding-sibling::class[ @name = 'link span f5 fw7 secondary']").click()
self.driver.find_elements_by_xpath("//span[contains(text(), '18F') or contains(text(), '20M')])/preceding-sibling::class[ @name = 'link span f5 fw7 secondary']").click()

但我得到了错误:

actions.move_to_element(element, 0, 0).perform()
TypeError: move_to_element() takes 2 positional arguments but 4 were given

我是新来的,所以我不知道我是否朝着正确的方向前进,任何帮助都将不胜感激。非常感谢。

所以我今天玩了一下,发现了如何打开单个AgeEx:的url

self.driver.find_element_by_xpath("//span[contains (.,'23F')]").click();

我决定走另一条路,而不是点击一个元素,列出所有的url。

self.driver.find_element(By.XPATH,"//span[contains (.,'30F')]/preceding-sibling::a[1]").get_attribute('href')

不过,上面只是一个AgeSex,所以我必须为每个选项写出来。如果一个不存在,它会抛出一个错误,所以我为每个写了一个try-and-except块:

try:
if self.driver.find_element(By.XPATH, "//span[contains (.,'27F')]").is_displayed():
user27 = self.driver.find_element(By.XPATH,"//span[contains (.,'27F')]/preceding-sibling::a[1]").get_attribute('href')
if user27 not in urls:
urls.append(user27)
except:
pass

如果存在属性,则会将href添加到列表中。

我觉得必须有更好的写作方式。一种更有效的方法,不需要10-15次尝试,除了阻止

我可以使用以下命令执行单击:

driver.find_element_by_xpath("//span[contains(., '18F') or contains(., '20M')]/preceding-sibling::a[@class = 'link span f5 fw7 secondary']").click()

这里有一些注意事项:

  1. 对于前面的同级,语法是前面的同级::{xPath}-->上一个同级::tagname[@attibute='value']

  2. 我建议您使用find_element_by xpath(单数(而不是find_elements_by_xpath(复数(,因为最新返回的是一个列表,它没有click()函数。如果要单击多个元素,请使用find_elements_by_xpath列出这些元素,然后对它们进行迭代,以单击每个元素的前一个同级元素。

例如:

elems = driver.find_elements_by_xpath("//span[contains(., '18F') or contains(., '20M')]")
for elem in elems:
elem.find_element_by_xpath("./preceding-sibling::a[@class = 'link span f5 fw7 secondary']").click()

最新更新