Can't find the element and can't define na

2019-07-18 07:34发布

I want to build an auto login bot or something. It has two parts: 1.login 2.verify login The last line of the login part finds and clicks on a button(Log In). When I run only the login part it works, but when I add verifying lines it doesn't work and can't find the button to click.

Then I use Explicit Waits but it can't define the name "element". I'm confused.

Here's the code:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("My Website")
username = driver.find_element_by_xpath("//input[@name='username']")
password = driver.find_element_by_xpath("//input[@name='password']")
username.clear()
username.send_keys("My Username")
password.clear()
password.send_keys("My Password")
driver.find_element_by_xpath("//div[@type='submit']").click()
if len(driver.find_elements_by_xpath("//input[@name='username']"))>0:
    print("Not!")
else:
    print ("Logged IN!")

The second code(Explicit Waits added):

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

driver = webdriver.Firefox()
driver.get("My Website")
username = driver.find_element_by_xpath("//input[@name='username']")
password = driver.find_element_by_xpath("//input[@name='password']")
username.clear()
username.send_keys("My Username")
password.clear()
password.send_keys("My Password")
try:
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.XPATH, "//div[@type='submit']"))
    )
finally:
    element.click()

if len(driver.find_elements_by_xpath("//form[@id='slfErrorAlert']"))>0:
    # Element is present
    print("Not!")
else:
    # Element is not present
    print ("Logged IN!")

My Website is https://www.instagram.com/accounts/login/ if it helps.

Result for the first code:

>>> from selenium import webdriver
>>> from selenium.webdriver.common.keys import Keys
>>> driver = webdriver.Firefox()
>>> driver.get("My Website")
>>> username = driver.find_element_by_xpath("//input[@name='username']")
>>> password = driver.find_element_by_xpath("//input[@name='password']")
>>> username.clear()
>>> username.send_keys("My Username")
>>> password.clear()
>>> password.send_keys("My Password")
>>> driver.find_element_by_xpath("//div[@type='submit']").click()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "E:\A\Python3.7.3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 394, in find_element_by_xpath
    return self.find_element(by=By.XPATH, value=xpath)
  File "E:\A\Python3.7.3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 978, in find_element
    'value': value})['value']
  File "E:\A\Python3.7.3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "E:\A\Python3.7.3\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: //div[@type='submit']

>>> if len(driver.find_elements_by_xpath("//input[@name='username']"))>0:
...     # Element is present
...     print("Not!")
... else:
...     # Element is not present
...     print ("Logged In!")
...
Logged In!
>>>

Result for the second code:

>>> 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
>>>
>>> driver = webdriver.Firefox()
>>> driver.get("My Website")
>>> username = driver.find_element_by_xpath("//input[@name='username']")
>>> password = driver.find_element_by_xpath("//input[@name='password']")
>>> username.clear()
>>> username.send_keys("My Username")
>>> password.clear()
>>> password.send_keys("My Password")
>>> try:
...     element = WebDriverWait(driver, 10).until(
...         EC.presence_of_element_located((By.XPATH, "//div[@type='submit']"))
...     )
... finally:
...     element.click()
...
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
  File "E:\A\Python3.7.3\lib\site-packages\selenium\webdriver\support\wait.py", line 80, in until
    raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
NameError: name 'element' is not defined
>>> if len(driver.find_elements_by_xpath("//form[@id='slfErrorAlert']"))>0:
...     # Element is present
...     print("Not!")
... else:
...     # Element is not present
...     print ("Logged In!")
...
Logged In!

: It shows Logged In! because I verify Login by the error message that says the username or password is invalid. When the login button isn't clicked, the message doesn't turn up and the bot(program,code,...) thinks that you logged in.

2条回答
祖国的老花朵
2楼-- · 2019-07-18 08:14

Use WebdriverWait and element_to_be_clickable. However you have provided wrong tag name in xpath. Instead of div tag name should be button

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

driver = webdriver.Firefox()
driver.get("https://www.instagram.com/accounts/login/")

username =WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='username']")))
password =WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='password']")))
username.clear()
username.send_keys("My Username")
password.clear()
password.send_keys("My Password")
try:
    element = WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.XPATH, "//button[@type='submit']"))
    )
finally:
    element.click()

if len(driver.find_elements_by_xpath("//form[@id='slfErrorAlert']"))>0:
    # Element is present
    print("Not!")
else:
    # Element is not present
    print ("Logged IN!")
查看更多
别忘想泡老子
3楼-- · 2019-07-18 08:26

There is no div with the type='submit' in the login page.

Change the Login button xpath as below.

//button[.='Log In']
查看更多
登录 后发表回答