问题
I am trying to automate process of sign up on virus total site and for this using selenium in python. But having a problem while getting element by id. i am stuck in this any help will be appreciated thanks. here is my code i am trying.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
driver =webdriver.Chrome()
driver.get('https://www.virustotal.com/gui/join-us')
print(driver.title)
search = driver.find_element_by_id("first_name")
search.send_keys("Muhammad Aamir")
search.send_keys(Keys.RETURN)
time.sleep(5)
driver.quit()
回答1:
The First name field within the website https://www.virustotal.com/gui/join-us is located deep within multiple #shadow-root (open)
.
Solution
To send a character sequence to the First name field you have to use shadowRoot.querySelector() and you can use the following Locator Strategy:
Code Block:
from selenium import webdriver import time options = webdriver.ChromeOptions() options.add_argument("start-maximized") options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option('useAutomationExtension', False) driver = webdriver.Chrome(options=options, executable_path=r'C:\WebDrivers\chromedriver.exe') driver.get("https://www.virustotal.com/gui/join-us") time.sleep(7) first_name = driver.execute_script("return document.querySelector('vt-virustotal-app').shadowRoot.querySelector('join-us-view.iron-selected').shadowRoot.querySelector('vt-ui-two-column-hero-layout').querySelector('vt-ui-text-input#first_name').shadowRoot.querySelector('input#input')") first_name.send_keys("Muhammad Aamir")
Browser Snapshot:
References
You can find a couple of relevant discussions in:
- Unable to locate the Sign In element within #shadow-root (open) using Selenium and Python
回答2:
If you look at the HTML of the website, you can see that your input field is within a so called #shadowroot
.
These shadowroots prevent you from finding the elements contained within the shadowroot using a simple find_element_by_id
. You can fix this by finding all the parent shadowroots that contain the element you are looking for. In each of the shadowroots you will need to use javascript's querySelector and find the next shadowroot, until you can access the element you were looking for.
In your case you would need to do the following:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
driver =webdriver.Chrome()
driver.get('https://www.virustotal.com/gui/join-us')
print(driver.title)
# wait a bit untill form pops up
time.sleep(3)
# Retrieve the last shadowroot using javascript
javascript = """return document
.querySelector('vt-virustotal-app').shadowRoot
.querySelector('join-us-view').shadowRoot
.querySelector('vt-ui-text-input').shadowRoot"""
shadow_root = driver.execute_script(javascript)
# Find the input box
search = shadow_root.find_element_by_id("input")
search.send_keys("Muhammad Aamir")
search.send_keys(Keys.RETURN)
time.sleep(5)
driver.quit()
来源:https://stackoverflow.com/questions/62864415/how-to-locate-the-first-name-field-within-shadow-root-open-within-the-website