Use Selenium to enter search text into Google - python

I want to go to Google, and type in "Hello world" using Selenium + Python.
from selenium import webdriver
import time
import json
driver = webdriver.PhantomJS(executable_path='/usr/local/lib/node_modules/phantomjs/lib/phantom/bin/phantomjs')
driver.get("http://www.google.com")
Everything up until this part works fine. But now I'm having trouble understanding how I'd select their text field and enter text. The searchbar has an ID #gbqfq, but the below code returns an error.
driver.webElement('body', 'gbqfq')
Error:
'WebDriver' object has no attribute 'webelement'
Here are the docs:
http://selenium-python.readthedocs.org/en/latest/api.html#module-selenium.webdriver.remote.webelement

There are more than one way to find an Element. In your case, the easiest approach would be find_element_by_id. Your code would look like:
driver.find_element_by_id()
There are many other ways to find an element, such as find an element by Xpath, by CSS selector and etc.
I am not really sure why you had a "webElement" in your code, is it a typing mistake?

Related

Selenium - can't get the correct XPath using Chrome inspect elements - #id="layers" vs #id="react-root" - Python

Trying to get the correct XPATH for the username box for the Twitter login.
My (simplified) code is:
from selenium import webdriver
from selenium.webdriver import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time
driver_service = Service(executable_path=CHROME_DRIVER_PATH)
driver = webdriver.Chrome(service=driver_service)
url = "https://twitter.com/login"
driver.get(url)
user_name_box = driver.find_element(By.XPATH, value='//*[#id="react-root"]/div/div/div/main/div/div/div/div[2]/div[2]/div/div[5]/label/div/div[2]')
user_name_box.click()
Then, for whatever reason, Selenium can't find the element, and when I searched for the solution, the correct XPATH is '//*[#id="layers"]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div/div/div/div[5]/label/div/div[2]/div/input'
I suspect with my limited knowledge that this has something to do with React and the fact that the Twitter login box layers on top... but how do I access the correct XPath? Is there any way to select the correct XPath using Chrome? Or another tool?
Thanks very much. This is my first post on StackOverflow so be gentle :)
I was expecting that I could grab the correct XPath and then of course got an error. Googled the correct XPath, found it, but would like to know what's happening and how to grab the correct XPaths if elements are sitting in layers.
A manual procedure using xml2xpath can be used to show all possible XPath expressions from an HTML/XML source.
Saving the page source from the browser or the Outer Html from dev console to a file and passing a starting XPath expression:
xml2xpath.sh -s '//*[#id="react-root"]' -l tmp.html
Result using Outer Html
XPath expressions found: 99 (51 unique elements, use -r to override)
//*[#id="react-root"]
//*[#id="react-root"]/div
//*[#id="react-root"]/div/div
//*[#id="react-root"]/div/div/div
... [redacted]
//*[#id="react-root"]/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/label/div
//*[#id="react-root"]/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/label/div/div
//*[#id="react-root"]/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/label/div/div/div
//*[#id="react-root"]/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/label/div/div/div/span
//*[#id="react-root"]/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/label/div/div/div/input
//*[#id="react-root"]/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/span
//*[#id="react-root"]/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/span/span
//*[#id="react-root"]/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div/span/span/span
//*[#id="react-root"]/div/div/div/main
//*[#id="react-root"]/div/div/div/main/div
//*[#id="react-root"]/div/div/div/main/div/div
Testing an specific XPath expression to be used in Selenium
xml2xpath.sh -s '//*[#id="react-root"]//input[#autocomplete="username"]' -l tmp.html
Result (meaning expression matched elements)
XPath expressions found: 1 (1 unique elements, use -r to override)
//*[#id="react-root"]//input[#autocomplete="username"]
xml2xpath it's a bash script wrapper around xmllint XML tool.
If -a option is passed, absolute XPaths are returned similar to browser does
/html/body/div
/html/body/div/#id
/html/body/div/#style
/html/body/div/div
/html/body/div/div/#class
/html/body/div/div/div
/html/body/div/div/div/#class
/html/body/div/div/div/style
/html/body/div/div/div/div[1]/#aria-label
/html/body/div/div/div/div[1]/#class
/html/body/div/div/div/div[1]/#id
/html/body/div/div/div/div[2]/#class
/html/body/div/div/div/div[2]/#id
/html/body/div/div/div/div[1]/svg
/html/body/div/div/div/div[1]/svg/#viewbox
/html/body/div/div/div/div[1]/svg/#aria-hidden
/html/body/div/div/div/div[1]/svg/#class
/html/body/div/div/div/div[1]/svg/g
/html/body/div/div/div/div[1]/svg/g/path
/html/body/div/div/div/div[1]/svg/g/path/#d
/html/body/div/div/div/div[1]
/html/body/div/div/div/div[2]
/html/body/div/div/div/div[2]/form
/html/body/div/div/div/div[2]/form/#action
/html/body/div/div/div/div[2]/form/#method
/html/body/div/div/div/div[2]/form/div
/html/body/div/div/div/div[2]/form/div/#class
/html/body/div/div/div/div[2]/form/div/div
/html/body/div/div/div/div[2]/form/div/div/#dir
/html/body/div/div/div/div[2]/form/div/div/#class
/html/body/div/div/div/div[2]/form/div/div/#style
/html/body/div/div/div/div[2]/form/div/div/span
/html/body/div/div/div/div[2]/form/div/div/span/#class
/html/body/div/div/div/div[2]/form/div/br
/html/body/div/div/div/div[2]/form/div/input[1]
/html/body/div/div/div/div[2]/form/div/input[2]
/html/body/div/div/div/div[2]/form/div/input[1]/#type
/html/body/div/div/div/div[2]/form/div/input[1]/#name
/html/body/div/div/div/div[2]/form/div/input[1]/#value
/html/body/div/div/div/div[2]/form/div/input[2]/#type
/html/body/div/div/div/div[2]/form/div/input[2]/#value
NOTE: if source is an HTML fragment, /html/body are added by xmllint on what seems to be a bug.

Python Webelement to .text selenium

I use Selenium,
I would like to know how to retrieve the two values ​​result.name and result.prix under value 'text' and be able to save in text format I find myself with the code below with two webelement value which is displayed only on my console but I can not save them.
Thanks for your help.
from selenium import webdriver
driver=webdriver.Chrome(executable_path="chromedriver.exe")
driver.get('https://www.ldlc.com/')
barre_de_recherche=driver.find_element_by_id("search_search_text")
barre_de_recherche.send_keys('Processeur socket 1200')
bouton_recherche=driver.find_element_by_class_name("submit")
bouton_recherche.click()
recuperation_nom=driver.find_elements_by_class_name("title-3")
recuperation_prix=driver.find_elements_by_class_name("price")
for resultat_nom in recuperation_nom:
print(resultat_nom.text)
for resultat_prix in recuperation_prix:
print(resultat_prix.text)

Can't find text element with selenium

I'm trying to use Selenium to create a new message in my mailbox. I have a problem with finding napisz (en: 'write') button on my e-mail website. I tried to use driver.find_element_by_link_text but it doesn't work. I've managed to go workaround this problem using xpath but I'm very curious why the first method fails.
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
browser = webdriver.Firefox()
browser.get('https://profil.wp.pl/login.html?zaloguj=poczta&url=https://poczta.wp.pl/profil/')
elem_login = browser.find_element_by_name('login_username')
elem_login.send_keys('stack_scraper_wp#wp.pl')
elem_password = browser.find_element_by_name('password')
elem_password.send_keys('thankyouforhelp')
elem_zaloguj_button = browser.find_element_by_id('btnSubmit')
elem_zaloguj_button.click()
browser.get('https://poczta.wp.pl/d635/indexgwt.html#start')
elem_napisz_button = browser.find_element_by_link_text('napisz')
elem_napisz_button.click()
EDIT: I've tried to used same xpath today but it failed. Is it possible that it's somehow dynamic causing the problem?
.find_element_by_link_text() looks for a elements only. In your case, this is the button element and cannot be located using this locator.

Selenium Python find element partial link text

I'm trying to use Pythons Selenium module to click on an element whose link has the text "xlsx" at the end of it. Below is the code I'm using and the details of the element. Can someone please see why Python is unable to find this element?
driver.find_element_by_partial_link_text('xlsx').click()
Here is the element details:
<a name="URL$2" id="URL$2" ptlinktgt="pt_new" tabindex="43" onfocus="doFocus_win0(this,false,true);" href="http:******/HSC8_CNTRCT_ITEMS_IMPRVD-1479218.xlsx" onclick="window.open('http:********/HSC8_CNTRCT_ITEMS_IMPRVD-1479218.xlsx','','');cancelBubble(event);return false;" class="PSHYPERLINK">HSC8_CNTRCT_ITEMS_IMPRVD-1479218.xlsx</a>
I had to remove some parts of the URL for confidentiality purposes, however, it should not impact the answering of the question.
Thanks.
Thanks for the replies. Turns out, as #Andersson mentioned, the window was in a different frame.
I solved the problem using the following code before the find_element: driver.switch_to.frame('ptModFrame_0').
You can use a CSS selector:
driver.find_element_by_css_selector("a[href*='xlsx']")
If the element still cannot be located, I would suggest using a wait statement, to ensure that the element is visible, before you interact with it.
Please try:
driver.find_element_by_xpath(".//a[contains(#href,'xlsx')]").
You can grab it by class name (class name = PSHYPERLINK).
This should work:
import selenium
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
url = ''
driver = webdriver.Chrome('/path/to/chromedriver/executable')
if __name__=='__main__':
driver.get(url)
time.sleep(3)
driver.find_element_by_class_name('PSHYPERLINK').click()
When finding the attribute, make sure to use a singular '"element". Like:
driver.find_element_by_class_name('PSHYPERLINK').click()
not:
driver.find_elements_by_class_name('PSHYPERLINK').click()
Hope this helps.

Extracting hidden element in Selenium

I have an element of type hidden in an iframe. I am wondering if there would be any way to get this value as I am using selenium. More specifically it is a captcha field. I've tried pulling it with something along the lines of
#!/usr/bin/env python
from selenium import webdriver
driver=webdriver.Chrome(chrome_bin_path)
driver.get('http://websitehere.com')
print driver.find_element_by_xpath('//*[#id="recaptcha-token"]').text
but because of it's hidden nature it returns nothing.
Below is a snippet of the source.
Highlighted is the string of interest. (value)
driver.switch_to_frame('undefined')
token_value = driver.find_element_by_id('recaptcha-token').get_attribute('value')
driver.switch_to_default_content()
Moving between windows and frames.
Use this method
hidden_text = element.get_attribute("textContent")

Categories

Resources