简体   繁体   中英

Python Selenium: send keys to tag 'input type="hidden" '

I try to log in to this web page with my credentials.

https://www.oddsportal.com/login

I am able to get the "username" and "password" input boxes but I am not able to send the data.

Selenium locates the elements (via "id" or otherwise), but gives problems when trying to send values or pressing enter: "AttributeError: 'NoneType' object has no attribute 'click'" "AttributeError: 'NoneType' object has no attribute 'send_keys'"

I've tried find, xpath, actionchain and execute_script, too.

Any clue how to click and send keys?

TVM.

I add some code tried:

us = driver.find_element_by_xpath('//input[@type="hidden"]')

print(us)

output:

<selenium.webdriver.remote.webelement.WebElement (session="84a2b7c7a5e9eda5e562d7a8f17ab749", element="1201c113-012c-4918-84cf-8011b696a5ff")>

I tried too:

us = driver.find_element(By.ID, "login-username-sign")

print(us)

output:

<selenium.webdriver.remote.webelement.WebElement (session="b8e6d51511c6cad8d24cf7946c46865f", element="004a920b-752d-4280-8dd1-5c8f330efa74")>

I tried:

us = driver.find_element(By.ID, "login-username-sign")

us.send_keys("1234")

output:

ElementNotInteractableException: Message: element not interactable
  (Session info: chrome=109.0.5414.74)

Etc.

"Info about human login": To log in manually you have to put the cursor over the text box, click and then type. This actions fail (click and type) under Selenium (I dont get it clicks but I think Selinium does get the object).

HTML:

<form action="https://www.oddsportal.com/userLogin" method="post" class="flex flex-col flex-1 mt-[10px]">
  <input type="hidden" name="_token" value="PhbLpoaq9vnNILGD4H6YYO7kFAoq2CUnT606hOHO"> 
  <input type="hidden" name="referer">
  <div class="item">
    <div class="title">
      <label for="login-username-sign" class="mb-2 text-xs text-black-main">Username</label>
      <span class="required" title="required item">*</span>
    </div>
    <div>
      <input class="int-text w-[300px] min-sm:w-[340px] pl-4 h-10 mb-[14px] border border-solid border-box border-black-main border-opacity-20 hover:input-hover" type="text" id="login-username-sign" name="login-username" size="25" required="">
    </div>
  </div>
<div class="item">
  <div class="title">
    <label for="login-password-sign" class="mb-2 text-xs text-black-main">Password</label>
    <span class="required" title="required item">*</span>
  </div>
  <div class="flex h-10 bg-white-main">
    <input class="int-text w-[300px] min-sm:w-[340px] pl-4 h-10 mb-[14px] border-solid border border-black-main border-opacity-20 hover:input-hover" type="password" id="login-password-sign" name="login-password" autocomplete="on" size="25" required="">
    <div class="grid absolute left-[90%] items-center justify-center h-10 w-8"><div onclick="switchVisibility(this, 'login-password-sign')" class="w-6 h-5 bg-center bg-no-repeat bg-cover cursor-pointer passlog bg-eye_icon !bg-off_eye_icon">
    </div>
  </div>
</div>

I can't open that link due to security policy of my working computer, but I can be quite sure that your problem is caused by bad locators.

"AttributeError: 'NoneType' object has no attribute 'click'"

and

"AttributeError: 'NoneType' object has no attribute 'send_keys'"

Means you did not actually get the web element you trying to click / send keys to.
Also sending keys (text) with Selenium to element with 'input type="hidden" ' is also not possible. Selenium imitates human user GUI actions. As a human user you can not insert text to hidden element.

There are 2 login forms on that page. Your Selenium code is failing because it locates the first one, which is hidden unless you press login in top right corner of the page: 在此处输入图像描述

If you press F12 in chrome devtools and try to search for element like this: document.querySelectorAll("div.pt-5 form #login-username-sign") it will find both login fields. This is a 'css' selector which you can use in your python code. Since it looks 'top to bottom' the easiest would be to do:

document.querySelectorAll("div.pt-5 form #login-username-sign")[1]

Here is a test of how it works, inside devtools:

在此处输入图像描述

To sum things up - you should be able to locate it with:

find_elements(By.CSS_SELECTOR, "div.pt-5 form #login-username-sign")[1]

find_elements returns a list of all elements matching that selector (we will get 2). Our login is the second one in DOM, so we pick [1] from the list.

  1. First of all, you have to register the website creating an account manually by filling blank form using Username, password, email and country name from the following url

  2. Then go with your desired login url and run the selenium code and see the real scenerio from the selenium automated browser. Now you willnotice that the login url will ask to fillthe form with the username and password only and you have to use your registered username and password and click on login button. That okey. Nope, At first, accept cookies. then fill up the login form.

  3. You have to apply JavaScript execution in order to click on Login button, Otherwise, it will throw ClickIntercept Exception. Because Login button interacts with other dynamic element.

Script:

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from webdriver_manager.chrome import ChromeDriverManager
import time
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_experimental_option("detach", True)

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()),options=options)   

URL ='https://www.oddsportal.com/login'
driver.get(URL)
time.sleep(5)

cookie_btn = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, '(//*[@id="onetrust-button-group"]/button)[1]'))).click()

UserName = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '(//*[@id="login-username-sign"])[2]'))).send_keys('Akij')#Your registered account's username

PassWord = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, '#login-password-sign'))).send_keys('789456rtU') #Your registered account's password

LogIn =  WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '(//*[@name="login-submit"])[2]')))
#You have to apply JavaSript execution in order to click on Login button, Otherwise it will throw ClickIntercept Exception 
#Because Login button interacts with other dynamic element.
LogIn_click = driver.execute_script("arguments[0].click();", LogIn) 
time.sleep(1)

See the below output:

Output-01

Output-02

You were close enough. However the locator strategy you were trying to use, ie

us = driver.find_element(By.ID, "login-username-sign")

identifies two (2) elements within the HTML DOM . Among them first one is hidden where as the second matching element is your desired element.

登录用户名登录


Solution

To cut sort the task of identifying the Username & Password field you can click on the LOGIN element in the top right corner of the page which opens the Username & Password fields within a Modal Dialog Box and you can identify the desired elements using the following locator strategies :

  • Code Block:

     from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC driver.get('https://www.oddsportal.com/login') WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button#.netrust-accept-btn-handler"))).click() WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='flex gap-3']//div[contains(@class, 'loginModalBtn') and starts-with(., 'Login')]"))).click() WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div#loginDiv form[action='https://www.oddsportal.com/userLogin'] input#login-username-sign"))).send_keys("daniel2014") driver.find_element(By.CSS_SELECTOR, "div#loginDiv form[action='https://www.oddsportal.com/userLogin'] input#login-password-sign-m").send_keys("daniel2014")
  • Browser Snapshot:

模态登录

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM