我正在尝试使用 selenium 编写一个 python 脚本,以使用输入的位置自动随机挑选一些东西作为晚餐。但是,我收到了以下错误消息:selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[@id="tsuid11"]/div[2]/div/a/div/div[3]/div"}
我真的不明白为什么会发生这个错误。我什至多次观察了整个进程的加载情况,并且确定 XPath 值是正确的。
这是我的代码:
import requests
import random
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
location = input("Please enter your postal code: ")
driver = webdriver.Chrome("<path to chromedriver.exe>")
query = "food near " + location
print("Please give us a moment...")
driver.get("https://www.google.com/search?q=" + query)
time.sleep(3)
#this helps to click the "View All" option to see the entire list of restaurants nearby
view_all = driver.find_element_by_xpath('//*[@id="rso"]/div[1]/div/div/div/div/div[5]/div/g-more-link/a/div/span[1]')
view_all.click()
time.sleep(10)
#This is where I can't seem to find the element by its XPath
name = driver.find_element_by_xpath('//*[@id="tsuid11"]/div[2]/div/a/div/div[3]/div')
print(name)
driver.close()
我也已经搜索了这个错误并得到了这个:here
根据答案,该人提到“可能是一种竞争条件,其中 find 元素在它出现在页面上之前正在执行”。不过,我已经添加了 time.sleep()
函数来缓解这种情况。
任何帮助将不胜感激:)
更新:我通过将 find by XPath
替换为 find by CSS Selector
使其正常工作。但是,这只是一种解决方法,我仍然会尝试解决这个问题。感谢您提供的所有解决方案,但不幸的是,没有一个对我有用。
经过一些进一步的探索,我在浏览器控制台本身上测试了完整的 XPath: /html/body/div[6]/div/div[7]/div[1]/div/div/div[2]/div[2]/div/div/div/div/div/div/div/div[1]/div[4]/div[3]/div[2]/div/a/div/div[3]/div
,但没有找到任何东西。通过挖掘图层,我注意到它停在 /html/body/div[6]/div/div[7]/div[1]/div/div/div[2]/div[2]/div/div/div/div/div/div/div/div[1]/div[4]/div[3]/div[2]/div
处,就在 a
标记之前。我现在不知道为什么,如果我发现任何东西会再次更新。
更新 2: 我使用了类名而不是 XPath,这对我的输出更加一致。这为我解决了所有问题 :) 希望这会有所帮助。
答案 0 :(得分:1)
点击 view All
后,您还没有提到您到底想做什么,如果我假设您想获取餐厅名称,您可以通过以下方法进行:
您可以在代码中的这两行之后编写以下代码:-
view_all.click()
time.sleep(10)
示例代码:
all_names = driver.find_elements(By.CSS_SELECTOR, "div[role='heading'] div")
print(all_names[0].text)
或者如果您想获取所有名称:-
names = []
for name in driver.find_elements(By.CSS_SELECTOR, "div[role='heading'] div"):
names.append(name.text)
print(names)
更新 1 :
driver = webdriver.Chrome("<path to chromedriver.exe>")
driver.maximize_window()
driver.implicitly_wait(30)
location = "545084"
query = "food near " + location
driver.get("https://www.google.com/search?q=" + query)
wait = WebDriverWait(driver, 10)
ActionChains(driver).move_to_element(wait.until(EC.element_to_be_clickable((By.XPATH, "//a[contains(@href, '/search?tbs')]")))).perform()
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[contains(@href, '/search?tbs')]"))).click()
names = []
for name in driver.find_elements(By.XPATH, "//div[@aria-level='3']"):
names.append(name.text)
print(names)
输出:
["Mum's Kitchen\nCatering Pte Ltd", 'Kitch', "Zoey's Diner", "McDonald's", 'ThaiExpress', 'Dian Xiao Er', "Swensen's", 'Pho Street Compass One', 'Singapore WaterDrop Tea House', 'LeNu at Compass One', "McDonald's Compass One", "McDonald's", 'Miami Bistro', 'Monster Curry', 'Texas Chicken (Hougang Capeview)', 'Paradise Hotpot at Compass One', "Long John Silver's Rivervale Mall", 'Boon Tong Kee @ Compass One', 'Din Tai Fung', 'Fish & Co.', 'PUTIEN', 'Soup Restaurant 三盅两件 - Compass One']
答案 1 :(得分:0)
请检查此元素是否在框架内,当我们使用调试器时,我们的元素会被识别,但代码不会知道。我们需要从根框架向下钻取 -> 对应框架 -> 那么元素将是难以处理的。
答案 2 :(得分:0)
#更改您的 xpath 以单击查看全部
view_all = driver.find_element_by_xpath('//*[@id="rso"]//span[normalize-space(text())="View all"]')
#这将打印所有餐厅名称
numberof_restaurants = driver.find_elements_by_xpath('//*[contains(@id,"tsuid")]//div[@role="heading"]')
for restaurant in numberof_restaurants:
name = restaurant.text
print(name)
答案 3 :(得分:0)
你可以试试下面几行代码,希望对你有帮助
location = input("Please enter your postal code: ")
driver = webdriver.Chrome("<path to chromedriver.exe>")
#I've try to open the browser in the maximize mode because when we try to click on the `veiw All` button sometime it through the Exception
driver.maximize_window()
query = "food near " + location
print("Please give us a moment...")
driver.get("https://www.google.com/search?q=" + query)
time.sleep(3)
#This XPath also gives me an error sometime, So I've updated it to click on restaurants nearby
view_all = driver.find_element_by_xpath("//*[text()='View all']")
view_all.click()
time.sleep(10)
#the provided xpath was not perfect I was not able to search it on the page, Also updated the print() with `.text` to get the text
name = driver.find_element_by_xpath("//div[@id='tsuid9']//a")
print(name.text)
driver.close()
你可以试试,点击带有explicitWait
viewAll = WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[text()='Viewall']")))
viewAll.click()
导入
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait