XPATH syntax for element in {} with Selenium for Python

Viewed 82

I am currently trying to click each button on a webpage with Selenium in Python, the class and text is always the same for each button but each button has different ids. The ids, however, are within "data-paramaters" in {} and I can't figure out how to get the correct syntax for the xpath. Here is a snippet of the website for one of the buttons:

<span class="contains-icon-details gc-btn gc-btn--s" data-isneededpromise="false" data-parameters="{"partner":"gs", "realId": "8da1d6a9-44d1-4556-bc12-92699749a30a", "tnId": "102086182829", "type": "details"}">More Details</span>

It seems the realId and the tnId are unique, so I would need to find the buttons with either one of those.

This works:

driver.find_element_by_xpath("//span[@class='contains-icon-details gc-btn gc-btn--s']").click()

but of course only for the first button as the class is always the same.

I tried something like this:

driver.find_element_by_xpath("//*[contains(@tnId, '102086182829')]").click()

but I get

Unable to locate element: //*[contains(@tnId, '102086182829')]

so definitely not the correct syntax.

I tried to find a solution online, but with no luck so far. Can anybody point me into the right direction? Thanks in advance.

2 Answers

In case realId value or tnId value is unique your XPath can be

driver.find_element_by_xpath("//*[contains(@data-parameters, '8da1d6a9-44d1-4556-bc12-92699749a30a')]").click()

or

driver.find_element_by_xpath("//*[contains(@data-parameters, '102086182829)]").click()

you should filter by the "data-parameters" attribute.

Try

driver.find_element_by_xpath("//span[contains(@data-parameters, '102086182829')]").click()

This is a dirty implementation of what you need. It would be better to extract the data-parameters field, deserialize JSON and check for the needed field;

spans = driver.find_element_by_xpath("//span[@class='contains-icon-details gc-btn gc-btn--s']")
for span in spans:
    data_parameters = span.get_attribute("data-parameters")
    try:
        data_parameters = json.loads(data_parameters)
    except:
        continue

    if 'tnId' in data_parameters and data_parameters['tnId'] == "102086182829":
        span.click()
        break
Related