find_element_by_* 命令在 selenium 中已弃用

find_element_by_* commands are deprecated in selenium

启动函数时

def run(driver_path):    
    driver = webdriver.Chrome(executable_path=driver_path)    
    driver.get('https://tproger.ru/quiz/real-programmer/')    
    button = driver.find_element_by_class_name("quiz_button")
    button.click()
run(driver_path)

我收到如下错误:

<ipython-input-27-c5a7960e105f>:6: DeprecationWarning: executable_path has been deprecated, please pass in a Service object
  driver = webdriver.Chrome(executable_path=driver_path)
<ipython-input-27-c5a7960e105f>:10: DeprecationWarning: find_element_by_* commands are deprecated. Please use find_element() instead
  button = driver.find_element_by_class_name("quiz_button")

...但我不明白为什么。

我在 chrome 的版本中使用最新版本的 webdriver。我不明白为什么我得到

`find_element_by_* commands are deprecated` 

...当文档中存在该命令时。

这个错误信息...

DeprecationWarning: find_element_by_* commands are deprecated. Please use find_element() instead

...暗示 find_element_by_* 命令在最新的 Selenium Python 库中被弃用。

As @AutomatedTester mentions:这个 DeprecationWarning 反映了关于简化跨语言 API 的决定所做的更改,而这就是这样做的。


解决方案

相反,您必须使用 find_element()。例如:

You have to include the following imports

from selenium.webdriver.common.by import By
  • 使用class_name:

    button = driver.find_element_by_class_name("quiz_button")
    

    需要替换为:

    button = driver.find_element(By.CLASS_NAME, "quiz_button")
    

在类似的行中,您还必须更改以下内容:

  • 使用id:

    element = find_element_by_id("element_id")
    

    需要替换为:

    element = driver.find_element(By.ID, "element_id")
    
  • 使用name:

    element = find_element_by_name("element_name")
    

    需要替换为:

    element = driver.find_element(By.NAME, "element_name")
    
  • 使用link_text:

    element = find_element_by_link_text("element_link_text")
    

    需要替换为:

    element = driver.find_element(By.LINK_TEXT, "element_link_text")
    
  • 使用partial_link_text:

    element = find_element_by_partial_link_text("element_partial_link_text")
    

    需要替换为:

    element = driver.find_element(By.PARTIAL_LINK_TEXT, "element_partial_link_text")
    
  • 使用tag_name:

    element = find_element_by_tag_name("element_tag_name")
    

    需要替换为:

    element = driver.find_element(By.TAG_NAME, "element_tag_name")
    
  • 使用css_selector:

    element = find_element_by_css_selector("element_css_selector")
    

    需要替换为:

    element = driver.find_element(By.CSS_SELECTOR, "element_css_selector")
    
  • 使用xpath:

    element = find_element_by_xpath("element_xpath")
    

    需要替换为:

    element = driver.find_element(By.XPATH, "element_xpath")
    

注意:如果您正在搜索和替换以实现上述更改,您将需要为 find_elements_* 做同样的事情,即[的复数形式=39=].

您可能还会发现此升级指南很有用,因为它涵盖了您在升级时可能需要进行的其他一些不相关的更改:https://www.selenium.dev/documentation/webdriver/getting_started/upgrade_to_selenium_4/

@DebanjanB 提到并解释了新结构,最好使用这些行:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service

s = Service('C:/Users/.../chromedriver.exe')
driver = webdriver.Chrome(service=s)

正如其他人提到的,您应该使用 find_element()find_elements() 而不是 find_element_by_*()find_elements_by_*()

我编写了正则表达式模式以将已弃用的方法替换为新的方法,所以如果需要请试试这个。

# from - e.g. find_element_by_id("test")

find_element(s?)_by_([a-z]+)\((.*)

# to - e.g. find_element(By.ID, "test")

find_element(By.\U\E, 

注意:您需要导入行才能使用新方法

from selenium.webdriver.common.by import By

这里有一个例子可以澄清一些事情:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

chrome_driver_path = "C:\Development\chromedriver_win32\chromedriver.exe"
s = Service(chrome_driver_path)
driver = webdriver.Chrome(service=s)

driver.get('https://www.amazon.in/Apple-MacBook-Chip-13-inch-256GB/dp/B08N5VSQNG/')
title = driver.find_element(by=By.ID, value="productTitle")  # by=By.ID, By.TAG_NAME, By.CLASS_NAME, By.NAME
print(title.text)


# driver.close()  # Closes the tab which was opened earlier
driver.quit()  # Quits the entire browser.