【问题标题】:Python Selenium Element not found and Not IntractablePython Selenium 元素未找到且不易处理
【发布时间】:2021-07-25 16:57:26
【问题描述】:

我正在尝试从moneycontrol.com抓取。当我尝试在搜索框中发送值时,我在除块中不断收到与“未找到元素”相同的错误。 我尝试使用 XPath id 以及 full XPath,但在这两种情况下都不起作用。

不最大化窗口

XPath id - //*[@id="search_str"]
完整 XPath - /html/body/div[1]/header/div[1]/div[1]/div/div/div[2]/div/div/form/input[5]

附上完整代码:

import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys

def search_stock():
    driver = webdriver.Chrome(
        r'./chromedriver')
    driver.get('https://www.moneycontrol.com/')
    time.sleep(5)
    search_icon = driver.find_element_by_xpath(
        '//*[@id="fixedheader"]/div[4]/span')
    search_icon.click()
    time.sleep(2)
    try:
        search_box = driver.find_element_by_xpath('//*[@id="search_str"]')
        print("Element is visible? " + str(search_box.is_displayed()))
        time.sleep(10)
        if search_box.is_displayed():
            search_box.send_keys('Zomato')
            search_box.send_keys(Keys.RETURN)
    except NoSuchElementException:
        print("Element not found")
    driver.close()

search_stock()

有时,它开始工作,但大多数时候它抛出异常和错误。自 3 天以来一直在苦苦挣扎,但没有一个解决方案有效。

【问题讨论】:

    标签: python-3.x selenium selenium-webdriver web-scraping selenium-chromedriver


    【解决方案1】:

    这样的网络抓取似乎效率很低,使用请求和 bs4 可能会更好。但是,如果您想这样做,您可以尝试使用动作链。 found here 或者你可以从一开始就输入 driver.get('https://www.moneycontrol.com/india/stockpricequote/consumer-food/zomato/Z') 而不是输入。

    【讨论】:

    • 嘿,我还有大量其他库存物品要报废,我不知道像这里这样的库存类型,您可以看到“消费品”并跟随 zomato。并且大部分股票可能在moneycontrol 上不可用,并且使用搜索选项我可以很好地处理错误。
    • 嘿,让我检查一下动作链。我对此了解不多。但让我试试。
    【解决方案2】:

    你可能想试试下面的代码:

    def search_stock():
        driver = webdriver.Chrome(r'./chromedriver')
        driver.maximize_window()
        driver.implicitly_wait(30)
        driver.get('https://www.moneycontrol.com/')
        wait = WebDriverWait(driver, 10)
        time.sleep(5)
        try:
            ActionChains(driver).move_to_element(wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[id='search_str']")))).perform()
            search_box = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[id='search_str']")))
            print("Element is visible? ", search_box.is_displayed())
            time.sleep(10)
            if search_box.is_displayed():
                search_box.send_keys('Zomato')
                search_box.send_keys(Keys.RETURN)
        except NoSuchElementException:
            print("Element not found")
    

    进口:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.action_chains import ActionChains
    

    【讨论】:

    • 嘿@cruisepandey,我得到 TimeOutException search_box = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[id='search_str']"))) 我没有必须最大化窗口。窗口最大化,可以搜索。
    • 你确定吗?它在我的机器上一切正常,我知道执行、运行它需要一些时间,并且不要进行任何手动干预
    • @Prateek :我不必最大化窗口。最大化窗口,可以搜索。 - 我不明白,你为什么不需要那个?如果我们不最大化屏幕,我们肯定会得到那个错误,因为元素不会在 Selenium 视口中。
    • 实际上,AWS 的 EC2 实例无法最大化我想要的大小,这就是我尝试不最大化的原因。
    • 通过最大化,它在我的机器上也能很好地工作。
    【解决方案3】:

    尝试点击search_box,然后再在那里发送文本。

    search_box = driver.find_element_by_xpath('//form[@id="form_topsearch"]//input[@id="search_str"]')
    search_box.click()
    time.sleep(0.1)
    search_box.send_keys('Zomato')
    search_box.send_keys(Keys.RETURN)
    

    另外,我建议您使用预期条件的显式等待而不是硬编码的睡眠。
    有了它,您的代码将更快、更可靠。

    import time
    from selenium import webdriver
    from selenium.common.exceptions import NoSuchElementException
    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
    
    def search_stock():
        driver = webdriver.Chrome(r'./chromedriver')
        wait = WebDriverWait(driver, 20)
        driver.get('https://www.moneycontrol.com/')
    
        wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="fixedheader"]/div[4]/span')).click()
    
        search_box =  wait.until(EC.element_to_be_clickable((By.XPATH, '//form[@id="form_topsearch"]//input[@id="search_str"]')))
        search_box.send_keys('Zomato')
        search_box.send_keys(Keys.RETURN)
        #I'm not sure you should close the driver immediately after involving searching....
        #driver.close()
    
    search_stock()
    

    UPD
    让我们试试这个

    import time
    from selenium import webdriver
    from selenium.common.exceptions import NoSuchElementException
    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
    from selenium.webdriver.common.action_chains import ActionChains
    
    
    def search_stock():
        driver = webdriver.Chrome(r'./chromedriver')
        wait = WebDriverWait(driver, 20)
        actions = ActionChains(driver)
    
        driver.get('https://www.moneycontrol.com/')
    
        search_icon = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="fixedheader"]/div[4]/span')).click()
        time.sleep(0.5)
        driver.execute_script("arguments[0].scrollIntoView();", search_icon)
        driver.execute_script("arguments[0].click();", search_icon)
    
        search_box =  wait.until(EC.presence_of_element_located((By.XPATH, '//form[@id="form_topsearch"]//input[@id="search_str"]')))
        driver.execute_script("arguments[0].scrollIntoView();", search_icon)
        driver.execute_script("arguments[0].click();", search_icon)
        time.sleep(0.5)
        search_box.send_keys('Zomato')
        search_box.send_keys(Keys.RETURN)
        #I'm not sure you should close the driver immediately after involving searching....
        #driver.close()
    
    search_stock()
    

    如果上述解决方案仍然不起作用,而不是

    actions.move_to_element(search_box).click().perform()
    

    试试

    driver.execute_script("arguments[0].click();", search_box)
    

    【讨论】:

    • 嘿,感谢您的超快速回答。我在 search_box 收到 TimeOutException。它无法点击,
    • 但是 search_icon 可以吗?
    • 是的,search_icon 点击​​得很好。但是这个 search_box = wait.until(EC.element_to_be_clickable((By.XPATH, '//form[@id="form_topsearch"]//input[@id="search_str"]'))) 仍然不能交互。跨度>
    • 没有。我什至没有在我的电脑上安装 python :) 不过别担心,我们会找到解决方案的
    • 请查看更新后的答案是否有效。我很奇怪为什么以前的解决方案不起作用
    猜你喜欢
    • 1970-01-01
    • 2021-12-17
    • 2018-11-07
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多