简体   繁体   English

Xpath 使用 text() 和 @class 作为条件定位元素

[英]Xpath to locate element using text() and @class as conditions

I am trying to automate adding items to cart in online shop, however, I got stuck on a loop that should differentiate whether item is available or not.我正在尝试自动将商品添加到在线商店的购物车中,但是,我陷入了一个应该区分商品是否可用的循环中。

Here's the loop:这是循环:

while True:
        #if ???
            WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, "//*[text()='" + size.get() + "']"))).click()
            sleep(1)
            WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, "//*[text()='Add to cart']"))).click()
            sleep(1)
            print("Success!")
            break
        else:
            driver.refresh()
            sleep(3)

If the size is available, button is active:如果尺寸可用,则按钮处于活动状态:

<div class="styles__ArticleSizeItemWrapper-sc-dt4c4z-4 eQqdpu">
    <button aria-checked="false" role="radio" class="styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs">
        <span class="styles__StyledText-sc-cia9rt-0 styles__StyledText-sc-1n1fwgw-2 styles__ArticleSizeItemTitle-sc-1n1fwgw-3 gnSCRf cLhSqA bipwfD">XL</span>
        <span class="styles__StyledText-sc-cia9rt-0 ffGzxX">
        </span>
    </button>
</div>

If not, button is inactive:如果不是,则按钮处于非活动状态:

<div class="styles__ArticleSizeItemWrapper-sc-dt4c4z-4 eQqdpu">
    <button disabled="" aria-checked="false" role="radio" class="styles__ArticleSizeButton-sc-1n1fwgw-0 fBeTLI">
        <span class="styles__StyledText-sc-cia9rt-0 styles__StyledText-sc-1n1fwgw-2 styles__ArticleSizeItemTitle-sc-1n1fwgw-3 gnSCRf cLhSqA bipwfD">XXL</span>
        <span class="styles__StyledText-sc-cia9rt-0 styles__StyledText-sc-1n1fwgw-2 kQJTJc cLhSqA">
        </span>
    </button>
</div>

The question is: what should be the condition for this loop?问题是:这个循环的条件应该是什么?

I have tried something like this:我尝试过这样的事情:

if (driver.find_elements(By.XPATH, "//*[contains(@class='styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs') and text()='" + e2.get() + "']")):

EDIT: Replaced "=" with "," in the above code as follows:编辑:在上面的代码中将“=”替换为“,”如下:

if (driver.find_elements(By.XPATH, "//*[contains(@class='styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs') and text()='" + e2.get() + "']")):

but I keep getting invalid xpath expression error.但我不断收到无效的 xpath 表达式错误。

EDIT: The error is gone, but the browser keeps refreshing with the else statement (element not found).编辑:错误消失了,但浏览器不断刷新 else 语句(未找到元素)。

I believe your error is in the use of the contains function, which expects two parameters: a string and a substring, although you're passing it a boolean expression ( @class='styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs' ).我相信您的错误在于使用contains函数,该函数需要两个参数:一个字符串和一个子字符串,尽管您向它传递了一个布尔表达式( @class='styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs' )。

I expect this is just a typo and you actually meant to type contains(@class, 'styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs') (NB comma instead of an equals sign after @class ).我希望这只是一个错字,而您实际上是要输入contains(@class, 'styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs') (注意@class后面的逗号而不是等号)。

Also, you are looking for a button element which has a child text node ( text() refers to a text node) which is equal to the size you're looking for, but that text node is actually a child of a span which is a child of the button .此外,您正在寻找一个button元素,它有一个子文本节点( text()指的是一个文本节点),它等于您正在寻找的大小,但该文本节点实际上是一个span的子节点,它是button的子项。 You can compare your size to the text value of that span .您可以将您的大小与该span的文本值进行比较。

Try something like this:尝试这样的事情:

"//*[contains(@class='styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs') and span='"
+ e2.get() 
+ "']"
e3="Some value"
x=f"//button[contains(@class,'styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs') and not(contains(@disabled='')) and ./span[contains(text(),'{e3}')]])]"
print(x)

Try looking for the button which contains that class and with that span and maybe check if button disabled?尝试查找包含该类并具有该跨度的按钮,并检查按钮是否已禁用?

I managed to get it working using this condition:我设法让它使用这种条件工作:

if (driver.find_elements(By.XPATH,
 "//*[contains(@class, 'styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs')
 and .//*[text()='" + e2.get() + "']]")): 

It is quite similar to the original approach, however, adding .//* before text() did the trick.它与原始方法非常相似,但是,在text()之前添加.//*就可以了。

Without .//* find_elements was looking in the same node which resulted in not finding the element.如果没有.//* find_elements在同一个节点中查找,导致找不到元素。 .//* instructs find_elements to look in the child node where element exists. .//*指示find_elements在元素所在的子节点中查找。

Important: text condition was wrapped in additional [] brackets.重要提示:文本条件包含在额外的[]括号中。

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

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