Im trying to automate blog posting using selenium and python
Able to locate element using Inspect element in browser
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
browser = webdriver.Firefox()
browser.get('https://www.blogger.com/go/signin')
email = browser.find_element_by_id('identifierId')
email.send_keys("xxxxxx#gmail.com")
email.send_keys(Keys.RETURN)
time.sleep(5)
password = browser.find_element_by_name("password")
password.send_keys("xxxxxx")
password.send_keys(Keys.RETURN)
time.sleep(5)
newpost = browser.find_element_by_partial_link_text("editor")
posttitle = browser.find_element_by_name("K3JSBVB-C-b titleField textField K3JSBVB-C-a")
error
Unable to locate element: [name="K3JSBVB-C-b titleField textField K3JSBVB-C-a"]
This K3JSBVB-C-b class attribute looks dynamic, I would rather suggest sticking to the New post text instead.
The relevant XPath expression would be something like:
//a[text()='New post']
Also consider using Explicit Wait as using sleep is an antipattern you should be avoiding
new_post = WebDriverWait(browser, 10).until(
expected_conditions.element_to_be_clickable(By.XPATH("//a[text()='New post']")))
new_post.click()
More information: How to use Selenium to test web applications using AJAX technology
Related
In the Xpath Helper plugin, I was able to get the HTML tag content:
QUERY://div[#id="cardModel"]/div[#class="modal-dialog"]/div[#class="modal-content"]//tr[1]/td[1]//tr/td[2]/div/span/text()
RESULTS (1):Enrico
The result is:
Enrico
But in Python:
from selenium import webdriver
from lxml import etree
driver = webdriver.Chrome()
detailUrl = 'https://www.enf.com.cn/3d-energy-1?directory=panel&utm_source=ENF&utm_medium=perc&utm_content=22196&utm_campaign=profiles_panel'
driver.get(detailUrl)
html_ele_detail = etree.HTML(driver.page_source)
time.sleep(5)
companyPhone = html_ele_detail.xpath('//div[#id="cardModel"]/div[#class="modal-dialog"]/div[#class="modal-content"]//tr[1]/td[1]//tr/td[2]/div/span/text()')
print("companyPhone = ", companyPhone)
companyPhone shows empty, what's wrong?Thank you all for solving this problem
As you are already using the selenium library, you do not need to use etree library.
For this application selenium library is enough
see the example below and adapt for your purpose:
from selenium import webdriver
driver = webdriver.Chrome()
detailUrl = 'your url here'
driver.get(detailUrl)
web_element_text = driver.find_element_by_xpath('your xpath directory here').text
print(web_element_text)
See some other examples in another topic by clicking here
Let me know if this was helpful.
I am trying to use Selenium to sign up an email account automatically whenever I need to. It's just a fun learning project for me. For the life of me I don't understand why it can't find the element. This code works fine on the sign-in page but not the sign-up page. I have tried all different Selenium commands and even tried using the ID and class name. Either is says it can't locate the element or that it is not reachable by keyboard.
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
import time
options = Options()
driver = webdriver.Firefox(options=options, executable_path=r'geckodriver.exe')
driver.get("https://mail.protonmail.com/create/new?language=en")
time.sleep(10)
username_input = driver.find_element_by_id("username").send_keys("testusername")
Also here is the HTML code: https://i.imgur.com/ZaBMTzG.png
The username field is in iframe, you need to switch to iframe to make this work.
Below is the code that works fine :
driver.get("https://mail.protonmail.com/create/new?language=en")
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='Registration form'][class='top']"))
driver.find_element_by_id("username").send_keys("some string")
read more about iframe here
learn more about how to switch to iframe/frame/framset using Python
selenium Bindings here
Update :
wait = WebDriverWait(driver, 30)
driver.get("https://mail.protonmail.com/create/new?language=en")
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='Registration form'][class='top']"))
driver.find_element_by_id("username").send_keys("some string")
driver.switch_to.default_content()
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
sleep(5)
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='Registration form'][class='bottom']"))
wait.until(EC.element_to_be_clickable((By.NAME, "submitBtn"))).click()
I'm not sure if I've seen enough code to diagnose, but I think the way you are defining username_input seems problematic. driver.find_element_by_id("username").send_keys("testusername") doesn't actually return anything so it seems like you are setting username_input = null.
Dear Stackoverflowers,
I'm trying to automate a CC payment process but Selenium is having a hard time identifying a specific element I want to click on. I'm trying to click on 'REI Card - 6137' so that I can continue to the payment page. Using the inspect tool it shows the class as, "soloLink accountNamesize". Unfortunately, there's not an ID I can go after. When I try to search by class name I get this error in the console:
selenium.common.exceptions.NoSuchElementException: Message: Unable to
locate element: .soloLink accountNamesize
Below is a picture of the site and the inspector pane with the thing I'm trying to click on highlighted in blue. Since its my credit card and I'm already logged it a link to the page wouldn't really help you guys.
The script gets hung up on "driver.find_element_by_class_name('soloLink accountNamesize').click()"
My code is below:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import yaml
import time
conf = yaml.load(open(r'D:\Users\Matt\Documents\GitHub\YML_Files\REI_Login_Credentials.yml'))
myREIUsername = conf['REILogin']['username']
myREIPassword = conf['REILogin']['password']
driver = webdriver.Firefox(
executable_path=
r'D:\Users\Matt\Documents\GitHub\Executable_Files\geckodriver.exe'
)
def login():
driver.get('https://onlinebanking.usbank.com/Auth/Login?usertype=REIMC&redirect=login&lang=en&exp=')
time.sleep(4)
driver.find_element_by_id('aw-personal-id').send_keys(myREIUsername)
driver.find_element_by_id('aw-password').send_keys(myREIPassword)
time.sleep(2)
driver.find_element_by_id('aw-log-in').click()
time.sleep(15)
make_payment()
def make_payment():
if (driver.find_element_by_class_name("accountRowLast").text) != "0.00":
driver.find_element_by_class_name('soloLink accountNamesize').click()
else:
driver.quit()
I've tried searching by Xpath and Xpath + Class with no luck. I also tried searching for this issue but its a fairly unique class so I didn't have much luck. Have any other ideas I could try?
soloLink accountNamesize is multiple class names use the following css selector instead to click on that element.
driver.find_element_by_css_selector('a.soloLink.accountNamesize').click()
To induce waits we do
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.soloLink.accountNamesize"))).click()
Based on the photo, I think that this is the xpath that you might want
//div[#id='MyAccountsDiv']//div[#id='CreditsTableDiv']//tbody//tr[#class='accountRowFirst']//a[contains(#onclick, 'OpenAccountDashboard')]
As you can see, this xpath starts off with the top-most div that might be unique ( MyAccountsDiv ) and continues to dive into the HTML code.
Based off of this, you could click on the link with the following code
xpath = "//div[#id='MyAccountsDiv']//div[#id='CreditsTableDiv']//tbody//tr[#class='accountRowFirst']//a[contains(#onclick, 'OpenAccountDashboard')]"
driver.find_element(By.XPATH, xpath).click()
NOTE
Your error says
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="aw-personal-id"]
Maybe you can use the above technique and see if you can isolate the xpath for the web element instead.
I want to build a simple app to learn Selenium in Python using a custom google search url to search Reddit and scrape the results:
https://cse.google.com/cse/publicurl?cx=011171116424399119392:skuhhpapys8
I am trying to click on the first link in the overlay that comes up after a search on the site as pictured here
image
I have so far:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
url = "https://cse.google.com/cse/publicurl?cx=011171116424399119392:skuhhpapys8"
driver = webdriver.Firefox()
driver.implicitly_wait(30)
driver.get(url)
python_button = driver.find_element_by_class_name('gsc-search-button')
inputElement = driver.find_element_by_id("gsc-i-id1")
soup_level1=BeautifulSoup(driver.page_source, 'lxml')
search = input("Ask Reddit")
inputElement.send_keys(search)
inputElement.send_keys(Keys.ENTER)
overlay = driver.find_element_by_class_name('gsc-results-wrapper-overlay')
first_link = driver.find_element_by_css_selector('a.gsc-title').click()
and I get the error
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: a.gsc-title
Any idea on what I am missing? Is there something special I have to do to deal with an overlay like that? There are multiple elements by that css selector am I not targeting the first?
The class for a link, as far as I can see is not gsc-title, it's gs-title. Hence your main problem. But also a couple of other things:
There's nothing special about overlay, no need to account for it. So overlay = driver.<...> is not required, unless you use it to make sure results showed up (see next point)
Changing implicit wait (driver.implicitly_wait(30)) is not a good idea; use explicit wait instead:
from selenium.webdriver.support import expected_conditions as EC
...
WebDriverWait(driver, 30).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "gsc-results-wrapper-overlay")))
first_link = driver.find_element_by_css_selector('a.gs-title').click()
Inspect
Im trying to click on this button to move to the login page.
my code is :
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://moodle.tau.ac.il/')
thats work fine but i can only find the form by using
loginform = driver.find_element_by_xpath("//form[#id='login']/")
I don't know how to get to the button, it's very basic stuff but I didn't find any good example.
This will click on the login button on moodle.tau.ac.il page.
The line driver.find_element_by_xpath(".//*[#id='login']/div/input").click() finds the login button on the page and clicks it. Xpath is just a selector type that you can use with selenium to find web elements on a page. You can also use ID, classname, and CSSselectors.
from selenium import webdriver
driver = new webdriver.Chrome()
driver.get('moodle.tau.ac.il')
# This will take you to the login page.
driver.find_element_by_xpath(".//*[#id='login']/div/input").click()
# Fills out the login page
elem = driver.find_element_by_xpath("html/body/form/table/tbody/tr[2]/td/table/tbody/tr[1]/td[2]/input")
elem.send_keys('Your Username')
elem = driver.find_element_by_xpath("html/body/form/table/tbody/tr[2]/td/table/tbody/tr[3]/td[2]/input")
elem.send_keys('Your ID Number')
elem = driver.find_element_by_xpath("html/body/form/table/tbody/tr[2]/td/table/tbody/tr[1]/td[2]/input")
elem.send_keys('Your Password')
driver.find_element_by_xpath("html/body/form/table/tbody/tr[2]/td/table/tbody/tr[7]/td[2]/input").click()
The page has two identical login forms and your XPath returns the hidden one.
So with the visible one:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get(r"http://moodle.tau.ac.il/")
driver.find_element_by_css_selector("#page-content #login input[type=submit]").click()
Or with an XPath:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get(r"http://moodle.tau.ac.il/")
driver.find_element_by_xpath("id('page-content')//form[#id='login']//input[#type='submit']").click()
You could find it using XPath as mentioned by #ChrisP
You could find it by CSS selector: "#login input[type='text']"
Or you could also just submit the form... loginForm.submit()
Ideally, you'd have a unique id for that button which would make it very easy to find.