我在Linux机器上运行Selenium headless,但它找不到特定的元素。然而,我在Windows机器上运行了完全相同的代码,它可以毫无问题地找到元素。我的Linux机器上有最新版本的驱动程序。有什么办法解决这个问题吗?
options = Options()
options.add_argument('--no-sandbox')
options.add_argument("--headless")
options.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/97.0.4692.71 Safari/537.36')
with webdriver.Chrome(options=options) as driver:
driver.get(url)
driver.find_element(By.ID, "btnhome").click()
video = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "video"))).get_attribute("src")
问题元素是视频元素。我也将等待时间增加到了2分钟,只是为了调试。它在Windows无头上运行良好,但在Linux无头上找不到。
感谢
2023更新:我正在修改我的原始答案以使用https://stackoverflow.com/a/73840130/7058266作为更好的解决方案。有一种新的Chrome无头模式,可以获得与常规Chrome相同的结果:
options.add_argument("--headless=new")
解决方案包括使用https://github.com/ponty/PyVirtualDisplay以便在诸如Linux的无头环境中模拟有头显示器。(这可以帮助您解决只有在使用无头浏览器加载网站时才会出现的问题。(虚拟显示器使用Xvfb
,实际上这里有一个非常流行的堆栈溢出解决方案:https://stackoverflow.com/a/6300672
以下是针对您的情况的先前解决方案的摘要:
安装:
pip install pyvirtualdisplay
以下是如何在Python代码中使用它:
from pyvirtualdisplay import Display
display = Display(visible=0, size=(800, 600))
display.start()
# display is active / Run your selenium code
# ----------
display.stop()
# display is stopped
把它们和你的代码放在一起后,它会看起来像这样:
from pyvirtualdisplay import Display
display = Display(visible=0, size=(800, 600))
display.start()
# ...
options = Options()
options.add_argument('--no-sandbox')
options.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/97.0.4692.71 Safari/537.36')
with webdriver.Chrome(options=options) as driver:
driver.get(url)
driver.find_element(By.ID, "btnhome").click()
video = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "video"))).get_attribute("src")
# ...
display.stop()
(根据需要进行修改,如屏幕分辨率等(
有些SeleniumPython框架已经内置了虚拟显示器(例如SeleniumBase,它通过添加的pytest
命令行arg:--xvfb
激活虚拟显示器。(每个内置了该功能的框架可能会做一些不同的事情。