How can I find the randomly Xpath using Selenium? - python

I am a newer in Selenium and use python to build it. Recently, I found a question which want to ask someone who can help me to figure it. The question is the Xpath I want to get is randomly, for example:
'//*[#id="wiki-edit-wikiEdit26"]/div/div/div/div[2]/a[1]'
'//*[#id="wiki-edit-wikiEdit27"]/div/div/div/div[2]/a[1]'
'//*[#id="wiki-edit-wikiEdit28"]/div/div/div/div[2]/a[1]'
These three xpath are used on the same button, but the number after wikiEdit will be changed every time. Therefore, are there any way which can help me to run my script more smoothly? Thank you very much!
Here is my python code:
broswer.find.element_by_xpath('//*[#id="wiki-edit-wikiEdit26"]/div/div/div/div[2]/a[1]') .click()

You can use matches in xpath to do this,
broswer.find.element_by_xpath("//*[matches(#id, '^(wiki-edit-wikiEdit)[0-9]')]/div/div/div/div[2]/a[1]") .click()
so basically that matches the id anything starting wiki-edit-wikiEdit followed by numbers form [0-9]

You just need to format your string..
import random
# Random range 1 - 100
x = random.randint(1,100)
broswer.find.element_by_xpath(f'//*[#id="wiki-edit-wikiEdit{x}"]/div/div/div/div[2]/a[1]') .click()

You can use starts-with or contains
broswer.find.element_by_xpath("//*[contains(#id,'wiki-edit-wikiEdit')]/div/div/div/div[2]/a[1]").click()
Also, using such long xpath's is not recommended. Use css-selectors over xpath.

Related

I'm having trouble selectiong an element using Selenium with Python

I want to read out the text in this html element using selenium with python. I just can't find a way to find or select it without using the text (i don't want that because its content changes)
<div font-size="14px" color="text" class="sc-gtsrHT jFEWVt">0.101 ONE</div>
Do you have an idea how i could select it? The conventional ways listed in the documentation seem to not work for me. To be honest i'm not very good with html what doesn't make things any easier.
Thank you in advance
Try this :
element = browser.find_element_by_class_name('sc-gtsrHT jFEWVt').text
Or use a loop if you have several elements :
elements = browser.find_elements_by_class_name('sc-gtsrHT jFEWVt')
for e in elements:
print(e.text)
print(browser.find_element_by_xpath("//*[#class='sc-gtsrHT jFEWVt']").text)
You could simply grab it by class name. It's 2 class names so it would be like so. by_class_name only uses one.
If the class name isn't dynamic otherwise you'd have to right click and copy the xpath or find a unique identiftier.
Find by XPath as long as font size and color attribute are consistent. Be like,
//div[#font-size='14px' and #color='text' and starts-with(#class,'sc-')]
I guess the class name is random?

Reference to XPath - is it possible?

I am using Selenium to automate a browser task through a Python script.
There is a text-box in my browser that I need to fill with info, but the XPath is formatted as below:
//*[#id="NameInputId14514271346457986"]
The problem is that: everytime the number before the Id (14514271346457986) changes. Is there a way to refer to this XPath something like:
//*[#id.start-with="NameInputId"]
Sorry if it is a dumb question - I started to using Selenium this week and I couldn't find this info on documentation.
You can test whether the first 9 characters of the #id value equals "NameInput", for an XPath 1.0 expression:
//*[fn:substring(#id, 1, 9) = "NameInput"]
With XPath 2.0 (and greater) you could use the starts-with() function:
//*[starts-with(#id, "NameInput")]
Sure, you can use xpath like //*[contains(#id,"NameInputId")] but I guess this possibly will not be an unique locator. In this case the xpath should be more complex to contain additional attributes or some parent element
you can use xpath like this
//*[#id[contains(.,'NameInputId')]]

Python Selenium help finding xpath

Can you help me? I need to find the element.
I have tried this so far :
browser.find_elements_by_xpath('//input[#type="text"]/text()')
browser.find_elements_by_xpath('//input[type="text"]/text()')
browser.find_elements_by_xpath('/input[#type="text"]/text()')
browser.find_elements_by_xpath('/input[type="text"]/text()')
browser.find_elements_by_xpath('//input[#type="text"]')
None of them turned out working. ):
Try the following:
browser.find_element_by_xpath('//input[contains(#class,"ScInputBase")]').get_attribute("value")
I guess it's a value, not a text.
Also use find_element_by_xpath, not find_elements_by_xpath
I'm not sure about the uniqueness of the locator I used since I can't see your page.

RegEx inside a string with selenium

I'm using selenium, with find_element_by_path method to do some web scraping, I have some problem to get a path which change through pages, I know how the path is written, but one of the string within the path change through my loop, I would like to know how can I use regex to solve it.
I have this code for one of the page but when I go through all pages the string "NUMBER" below changes:
browser.find_element_by_xpath(re.compile('//*[#id="exhibDetail:exhib"]/section[3]/div[2]/div/div[2]/div/div/div[NUMBER]/div').click()
I want to know if it was possible to use regex in order to say that it has to click whatever the "NUMBER" as long as the rest of the path is the same so I tried this but I'm not sure about the syntax and how to use regex here:
browser.find_element_by_xpath('//*[#id="exhibDetail:exhib"]/section[3]/div[2]/div/div[2]/div/div/div['). + re.compile("^[1-9]\d*$") + ']/div').click()
browser.find_element_by_xpath(re.compile('^//*[#id="exhibDetail:exhib"]/section[3]/div[2]/div/div[2]/div/div/div[')).click()
browser.find_element_by_xpath('//*[#id="exhibDetail:exhib"]/section[3]/div[2]/div/div[2]/div/div/div[1]/div').click()
browser.find_element_by_xpath('//*[#id="exhibDetail:exhib"]/section[3]/div[2]/div/div[2]/div/div/div[9]/div').click()
browser.find_element_by_xpath('//*[#id="exhibDetail:exhib"]/section[3]/div[2]/div/div[2]/div/div/div[4]/div').click()
browser.find_element_by_xpath('//*[#id="exhibDetail:exhib"]/section[3]/div[2]/div/div[2]/div/div/div[10]/div').click()
browser.find_element_by_xpath('//*[#id="exhibDetail:exhib"]/section[3]/div[2]/div/div[2]/div/div/div[6]/div').click()
the path evolves more or less in this manner (randomly) but not gradually one by one.
How do I solve this problem?
Welcome to SO.
If you are trying to pass the NUMBER as part of xpath in your loop then you can do the below.
If NUMBER in an integer:
browser.find_element_by_xpath("//*#id='exhibDetail:exhib']/section[3]/div[2]/div/div[2]/div/div/div[%i]/div"%(NUMBER)).click()
If NUMBER is a string
browser.find_element_by_xpath("//*#id='exhibDetail:exhib']/section[3]/div[2]/div/div[2]/div/div/div[%s]/div"%(NUMBER)).click()
I want to know if it was possible to use regex in order to say that it
has to click whatever the "NUMBER" as long as the rest of the path is
the same
If you want to select those div elements disregarding their position (that is what the predicates [1], [2], etc. are testing) then just don't use the predicates at all:
//*[#id="exhibDetail:exhib"]/section[3]/div[2]/div/div[2]/div/div/div/div

Python + Selenium: How can click on "onclick" elements?

I have an "onclick" element in a webpage whose HTML reads as follows:
Fastener
I want to search this element using the string "fastener" or "Fastener" using Python + Selenium. The number "3625" will change depending on previous inputs, and hence cannot be searched for.
I tried the following, but in vain:
br.find_element_by_css_selector("a[#onlick*='fastener']").click()
Please suggest ways to do this. Thank you!
P.S.: I am using Python 2.7, with Chrome WebDriver and Chrome v62.
To search the element with text as Fastener you can use either of the following options :
Through Fastener :
br.find_element_by_link_text("Fastener").click()
Using onclick through fastener (xpath):
br.find_element_by_xpath("//a[contains(#onclick,'fastener')]").click()
Using onclick through fastener (css_selector):
br.find_element_by_css_selector("a[onclick^='fastener']").click()
Use the following code for that:
br.find_element_by_link_text("Fastener").click()
Hope it helps you!
Using capybara-py:
page.click_link("Fastener")
Capybara is designed to provide this and many other similar helper methods, such as one might need to write acceptance tests from the perspective of end users:
page.fill_in("Street", value="123 Main St")
page.select("United States", field="Country")
page.choose("Expedited shipping")
page.click_button("Place order")
Use contains to search element
//a[contains (#onclick='fastener')]
OR
//a[contains(text(),"Fastener")]

Categories

Resources