I want to send 'username' using Selenium python, for the following html:
<div class="entryforms-elements">
<input id="entryforms-control-element" class="entryforms-element-text" type="text" autocomplete="off"></input>
</div>
But none of the following method worked:
browser.find_element_by_xpath('//input[#id="entryforms-control-element"]').send_keys('username')
browser.find_element_by_id('entryforms-control-element').send_keys('username')
browser.find_element_by_class_name('entryforms-element-text').send_keys('username')
Please help me!
You might want to check the size of the found element to be sure you are actually locating something.
If you are using firefox this might be getting in the way:
selenium webdriver is clearing out fields after sendKeys had previously populated them
Or some javascript might be munging the field after your keys are sent (maybe some js firing after page load).
You also might try calling click() first and then sending the keypresses -- perhaps that will help focus the element if it's the issue mentioned above or something similar.
Are you sure that the select by Xpatch is correct?
in my opinion should be something like that:
browser.find_element_by_xpath(".//*[#id='entryforms-control-element']")
in every case just to be sure is better you clean and then you introduce your input
browser.find_element_by_xpath(".//*[#id='entryforms-control-element']").clear()
browser.find_element_by_xpath(".//*[#id='entryforms-control-element']").send_keys('username')
in any case I advice you to use Firefox with the plugin firebug and firepath to know for sure the correct xpath of the elements
Jump on your browser developer tools and check how long it takes the element to load in the network tab. Then set a wait in your code between the load and element find based on this information.
Related
I'm working with a website where send_keys sometimes works and sometimes doesn't (I have no idea why). Sometimes it sends keys then I try a few hours later and it doesn't work anymore. I was wondering if anyone knew a way to send text/numbers into a input element WITHOUT using send_keys.
For example, would it be possible to input text into the following element without using send_keys:
<input _ngcontent-coh-c546="" type="text" name="tag" maxlength="25" placeholder="Tags" class="ng-dirty ng-valid ng-touched">
Any help would be greatly appreciated. Thank you.
This should work effectively and faster compared to send_key
from selenium import webdriver
driver = webdriver.Chrome('chromedriver')
driver.get("http://www.google.com");
driver.execute_script("document.getElementsByName('q')[0].value='What ever you want to be typed here'")
I'm creating an auto-login Google Calendar bot and I've run into an issue where the xpath for a certain element keeps changing every time I login(but it has a similar form). Here are some examples:
//[#id="c307"]/div/div[1]/div/div[2]/div/div[1]/div[1]/div/label/div[1]/div/input
//[#id="c236"]/div/div[2]/div[1]/div/div/span/div/div[1]/div[2]/div[1]/div/div[1]/input'
//*[#id="c27"]/div/div[1]/div/div[2]/div/div[1]/div[1]/div/label/div[1]/div/input
and etc.
How can I use Selenium to click on this dynamic element given that it always changes? Help will be much appreciated, thank you.
I would recommend using a querySelector over an xpath
MDN web docs document.querySelector
An implementation of this would look like:
driver.execute_script('document.querySelector("#specific_element_id").click()')
This code finds an element that looks something like <input type="button" id="specific_element_id"> and will click it.
url:https://www.zhihu.com/question/305744720/answer/557418746
use selenium can not reply answer,only human
options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
browser = webdriver.Chrome(executable_path='.\chromedriver.exe',chrome_options=options)
button_li = self.browser.find_elements_by_class_name('Button--blue')
if len(button_li) > 2:
print(len(button_li))
button_ele = button_li[4]
button_ele.click()
time.sleep(random.uniform(0.5, 3))
browser.find_element_by_css_selector('div.AnswerForm-editor').click()
time.sleep(random.uniform(0.5, 2))
js="""
var div=document.getElementsByClassName('public-DraftStyleDefault-block')
var text =document.createTextNode("君");
div[0].firstChild.appendChild(text)
"""
self.browser.execute_script(js)
browser.find_element_by_css_selector('Button.Button.AnswerForm-submit').click()
Summary of problem:
My problem is that I wrote the content to the answer box successfully, but I was identified as a machine. After that, my actions on the page seemed to stop working. How can I avoid being identified as a machine so that I can still use selenium to select my element?
I'm not sure where you are trying to select the submit button, but the following selector worked for me:
browser.find_element_by_css_selector('Button.Button.AnswerForm-submit').click()
With respect to being detected as a 'machine', it's not easy to avoid that.
There are several different ways they can detect you.
That said, here's one thing I found that can avoid some of the Selenium detection attempts. One thing they look for document variables called $cdc_ and $wdc_ that selenium uses, and for Chrome it would be $cdc_. Here is what I suggest you try:
Download a hex editor if you don't already have one. I used one from here.
open your chromedriver.exe in the hex editor.
Use the Search functionality to find any instance of $cdc_ or $wdc_ and replace basically any other string ending in an underscore. Myself, I found just one instance of $cdc_, and it looked like this:
'$cdc_asdjflasutopfhvcZLmcfl_'
I simply replaced it with 'Random_'
Hopefully this works and now you can traverse the site unimpeded. If not, try some of the following; the only problem with this is that it might break your chromedriver file so that the tests no longer work. But it could be worth a try, and if it does break you can easily download a fresh one.
Search the document for any usage of the words 'selenium', 'webdriver', or 'chromedriver' and delete them. These is another way that a site can tell you are using selenium.
Let me know if any of this helps or you have any questions. It's hard for me to come up with a concrete answer because I don't know how exactly the site is detecting selenium.
I am attempting to scrape the Census website for ACS data. I have scripted the whole processes using Selenium except the very last click. I am using Python. I need to click a download button that is in a window that pops when the data is zipped and ready, but I can't seem to identify this button. It also seems that the button might change names based on when it was last run, for example, yui-gen2, yui-gen3, etc so I am thinking I might need to account for this someone. Although I normally only see yui-gen2.
Also, the tag seems to be in a "span" which might be adding to my difficulty honing in on the button I need to click.
Please help if you can shed any light on this for me.
code snippet:
#Refine search results to get tables
driver.find_element_by_id("prodautocomplete").send_keys("S0101")
time.sleep(2)
driver.find_element_by_id("prodsubmit").click()
driver.implicitly_wait(100)
time.sleep(2)
driver.find_element_by_id("check_all_btn_above").click()
driver.implicitly_wait(100)
time.sleep(2)
driver.find_element_by_id("dnld_btn_above").click()
driver.implicitly_wait(100)
driver.find_element_by_id("yui-gen0-button").click()
time.sleep(10)
driver.implicitly_wait(100)
driver.find_element_by_id("yui-gen2-button").click()
enter image description here
enter image description here
Instead of using the element id, which as you pointed out varies, you can use XPath as Nogoseke mentioned or CSS Selector. Be careful to not make the XPath/selector too specific or reliant on changing values, in this case the element id. Rather than using the id in XPath, try expressing the XPath in terms of the DOM structure (tags):
//*/div/div/div/span/span/span/button[contains(text(),'Download')]
TIL you can validate your XPath by using the search function, rather than by running it in Selenium. I right-clicked the webpage, "inspect element", ctrl+f, and typed in the above XPath to validate that it is the Download button.
For posterity, if the above XPath is too specific, i.e. it is reliant on too many levels of the DOM structure, you can do something shorter, like
//*button[contains(text(),'Download')]
although, this may not be specific enough and may require an additional field, since there may be multiple buttons on the page with the 'Download' text.
Given the HTML you provided, you should be able to use
driver.find_element_by_id("yui-gen2-button")
I know you said you tried it but you didn't say if it works at all or what error message you are getting. If that never works, you likely have an IFRAME that you need to switch to.
If it works sometimes but not consistently due to changing ID, you can use something like
driver.find_element_by_xpath("//button[.='Download']")
On the code inspection view on Chrome you can right click on the item you want to find and copy the xpath. You can they find your element by xpath on Selenium.
I'm using Seleniun 2 webdriver (python) to run auto tests on IE browser.
One of major bugs in IE webdriver is that click() method does not work in 100% of cases. It happens sometimes when IE browser cannot set/looses focus on element. So, there's a workaround i googled to solve the problem- first the parent element must be clicked/selected. After that click() on the current element always works.
I would like to add my own method, named for ex. ieclick() that would do something like:
element = driver.find_element_by_id('id')
parentElement = element.find_element_by_xpath('..')
parentElement.click()
element.click()
Instead of writing all this code i would like to make:
driver.find_element_by_id('id').ieclick()
But i don't know how to implement this. I'm lost in Selenium modules code. I know that selenium class has click() method but i can't understand how can i rewrite it/add my own and make it useble for all this find_element_by_id, find_element_by_xpath etc.
Can someone help me to understand this implementation or maybe paste a link to some sort of explanation/example/lesson ?
The only reason that an element would not receive a click is because :
The element is disabled.
The element is invisible (therefore, cannot interact with it)
The element is not listening for any clicks (not binded)
My guess is that your "inconsistency issue" is coming form the third reason.
Consider the following:
<a href="dosomething">
<span id="spanclick">Click me</span>
</a>
Doing driver.find_element_by_id("spanclick").click() would not work, because it's the <a> element that is receiving the click, not the <span>.
It's your responsibility as the test writer to determine which element is receiving the click. My suggestion would be use debugging anytime you are in doubt. I've actually had a scenario where an <li> was receiving the actions of the mouse, not the <a>. By using Watch Expressions you are able to find what element is receiving the actions.
Seems i was exaggerating the difficulty.
selenium\webdriver\remote\webelement.py
Added code right after native click() method:
def ieclick(self):
"""2013-12-27. Surely clicks the element in IE."""
parent = self.find_element(by=By.XPATH, value='..')
parent._execute(Command.CLICK_ELEMENT)
try:
self._execute(Command.CLICK_ELEMENT)
except:
pass