1

I'm working on Python, Selenium and Chrome driver. I have a dynamic website and every time site loads the IDs get changed, Hence I can't use Xpath. But I can use the class name. I can get to the class as below; Following is the code of the site.

<a class="appButton registerItemSearch-tabs-criteriaAndButtons-buttonPad-search appSearchButton appPrimaryButton appButtonPrimary appSubmitButton appNotReadOnly appIndex2" id="nodeW830" href="#" onclick="return function(me){var retVal = false; if (catHtmlFragmentCallback('W830','buttonPush',null,{asyncUpdate:true,containerSelector:'#AsyncWrapperW814',containerNodeId:'W814',success:function(html){jQuery('#AsyncWrapperW814').empty().append(html);webuiAsyncOk('#AsyncWrapperW814');}}, me) == 'skip') retVal = true;return retVal;}(this)" tabindex="118"><span class="left"></span><span class="appReceiveFocus" tabindex="-1">Search</span><span class="right"></span></a>

However I can do the following; to get to the element.

xxx = driver.find_elements_by_class_name("appButton.registerItemSearch-tabs-criteriaAndButtons-buttonPad-search.appSearchButton.appButtonPrimary.appPrimaryButton.appSubmitButton.appNotReadOnly.appIndex2")

Now I want to execute onclick method associated with the class. I can do that as well like below;

driver.execute_script("return function(me){var retVal = false; if (catHtmlFragmentCallback('W830','buttonPush',null,{asyncUpdate:true,containerSelector:'#AsyncWrapperW814',containerNodeId:'W814',success:function(html){jQuery('#AsyncWrapperW814').empty().append(html);webuiAsyncOk('#AsyncWrapperW814');}}, me) == 'skip') retVal = true;return retVal;}(this)")

But as I mentioned, I can't hardcode the driver.execute_script values. I should get the values dynamically. Could you please help me? If you can suggest a way, that I can find the element by class name and execute onclick method. or as I mentioned; I can find the element by class name, if I can get the code (HTML)associated with the element then I can do driver.execute_script. Can you please suggest a way forward. Thank you

promax
  • 13
  • 4
  • Are you trying to click on the value in `xxx`? Use `xxx.click()`. – Jortega Jan 08 '20 at 17:21
  • Yes, could you please elaborate xxx.click() does not work. AttributeError: 'list' object has no attribute 'click' – promax Jan 08 '20 at 17:23
  • user `driver.find_element_by_class_name` not `driver.find_elements_by_class_name` – Jortega Jan 08 '20 at 17:24
  • 1
    Why u can't use xpath, I just didn't get it. Here is Xpath for your element (//span[@class='left']/parent::a), its works I'm just checked it and it doesn't depend on any dynamic attributes. Use same approach for other elements. – IPolnik Jan 08 '20 at 17:31
  • Hi driver.find_element_by_class_name has a click method. Thank you for pointing it out. But I need to execute the JS associated with the click. Just click() won't work. – promax Jan 08 '20 at 17:38
  • I’m voting to close this, since it’s a simple “How do I do scrape this” question which is only relevant to this extremely specific situation. – AMC Jan 08 '20 at 18:01
  • I was trying to sort this out, the whole day. I couldn't find the way. In my opinion, this is an answer to a question when the site is dynamic. The id's get change every time the page loads. It also answers how to get to an element using a class structure. How to execute an associated method and also tie it all with EC. I think it is a great answer. – promax Jan 08 '20 at 18:16

1 Answers1

0

Induce WebDriverWait and element_to_be_clickable() and following locator.

Xpath:

WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//a[.//span[text()='Search']]"))).click()

CSS selector:

WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"a.appButton.registerItemSearch-tabs-criteriaAndButtons-buttonPad-search.appSearchButton.appPrimaryButton.appButtonPrimary.appSubmitButton.appNotReadOnly.appIndex2"))).click()

You need to import following libraries.

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
KunduK
  • 32,888
  • 5
  • 17
  • 41
  • 1
    Thanks a lot, Kunduk, above works, I intend to use the CSS selector. I feel safer than XPath. Thanks again. – promax Jan 08 '20 at 17:54