无法使用无头 chrome 在网页上定位元素

Posted

技术标签:

【中文标题】无法使用无头 chrome 在网页上定位元素【英文标题】:Unable to locate elements on webpage with headless chrome 【发布时间】:2018-04-29 05:35:39 【问题描述】:

我有一个正在访问打印机的脚本,当 chrome 正常运行时,我的代码完全可以正常运行,但是当它无头运行时,selenium 似乎无法在网页上找到元素。

以下是相关代码:

初始化方法:

def __init__(self, ip_address):
    """ Initialize a new Printer_Webpage object."""
    self.ip_address = ip_address
    chrome_options = Options()
    chrome_options.add_argument("--headless")
    chrome_options.add_argument("--disable-gpu")
    chrome_options.add_argument("--window-size=1920x1080")
    self.browser = webdriver.Chrome(chrome_options=chrome_options)
    # Ignore lack of cert for each printer web page.
    # Otherwise, can't open page.
    self.browser.accept_untrusted_certs = True

登录方式:

def login(self):
    """Navigates through the login page for the printer."""
    # Open login page
    self.browser.get(f'https://self.ip_address/wcd/top.xml')
    # STEPS TO LOGIN:
    # 1) Select 'Administrator' radio button and click.
    self.browser.find_element_by_id('Admin').click()
    # 2) Select Login button and click.
    self.browser.find_element_by_xpath("//input[@type='submit' \
                                        and @value='Login']").click()
    # 3) Select admin (user mode)
    self.browser.find_element_by_id('R_ADM2').click()
    # 4) Select password field and input PASSWORD, then submit.
    password_field = self.browser.find_element_by_id('Admin_Pass')
    password_field.send_keys(PASSWORD)
    password_field.send_keys(Keys.RETURN)

完整的错误信息:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: "method":"id","selector":"Admin"

还有一些其他可能有用的信息:

(Session info: headless chrome=62.0.3202.94)

(Driver info: chromedriver=2.33.506120 (e3e53437346286c0bc2d2dc9aa4915ba81d9023f),platform=Windows NT 10.0.14393 x86_64)

【问题讨论】:

让无头浏览器截屏。这可能是先滚动到元素的问题,或者您可能需要在初始化无头浏览器时调整它的大小 - 如果它不够大,则该网站的大小可能适合移动设备并且在该视图中没有管理链接。 窗口大小使用逗号:--window-size=1920,1080。截取屏幕截图或从页面中转储 html 以找出该元素不存在的原因。 好的,我发现网页没有正确加载,最后只显示一个空白页。正常加载时,页面有几秒钟是白色的,所以我尝试使用 time.sleep(30) 给它足够的时间来加载,它仍然显示为白色页面。 Chrome-headless 不适用于无效的 https 证书。你只会得到一个空白页!见bugs.chromium.org/p/chromium/issues/detail?id=721739 谢谢!是否没有解决此问题的方法,还是我必须切换到其他无头浏览器? 【参考方案1】:

我遇到了同样的问题。您可以截屏以了解问题所在。

driver.get_screenshot_as_file("screenshot.png")

selenium 在正常运行时工作但在无头模式下停止工作的几个原因 -

1)它可能已切换到移动模板。可以通过改变窗口大小来修复。

chrome_options.add_argument("--window-size=1920,1080")

2)如果它是一个空白页面(截图),可能是由于 SSL 证书无效。(请参阅@Marcel_Wilson 帖子)它应该由 -

修复
chrome_options.add_argument('--ignore-certificate-errors')
chrome_options.add_argument('--allow-running-insecure-content')

3) 网站可能会阻止“无头”模式。 (您的屏幕截图可能会显示您无法在正常模式下重新创建的错误) 你可以试试这个-

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'
options.add_argument(f'user-agent=user_agent')

但是,如果网站有更强大的阻止方法,则上述代码将不起作用。你可以在这里https://intoli.com/blog/making-chrome-headless-undetectable/找到更多相关信息。

【讨论】:

Raj 对我来说是第 3 号,我在这里发布了一个更深入的答案,因为还有其他事情需要注意,因为该站点进行了一些更改以阻止 headless 也无法正常工作早期版本的 Chrome:***.com/a/69464060/1871891【参考方案2】:

我遇到了同样的情况。经研究,以下是正确的:

self.chrome_options = webdriver.ChromeOptions()
self.chrome_options.add_argument("--window-size=1920,1080")
self.chrome_options.add_argument("--disable-extensions")
self.chrome_options.add_argument("--proxy-server='direct://'")
self.chrome_options.add_argument("--proxy-bypass-list=*")
self.chrome_options.add_argument("--start-maximized")
self.chrome_options.add_argument('--headless')
self.chrome_options.add_argument('--disable-gpu')
self.chrome_options.add_argument('--disable-dev-shm-usage')
self.chrome_options.add_argument('--no-sandbox')
self.chrome_options.add_argument('--ignore-certificate-errors')
self.browser = webdriver.Chrome(options=self.chrome_options)

【讨论】:

【参考方案3】:

如果 SSL 证书有问题,您可以使用命令行标志在没有证书的情况下启动 Chrome(假设您是这样启动它的)。我相信开关是--allow-running-insecure-content,我从这个列表中找到了here。

【讨论】:

【参考方案4】:

@siking 在 cmets 中指出...

Chrome-headless 不适用于无效的 https 证书。你 只会得到一个空白页!看 http://bugs.chromium.org/p/chromium/issues/detail?id=721739

【讨论】:

【参考方案5】:

我遇到了同样的问题,发现元素在 headless 中加载速度较慢。 通过添加以下代码行,问题就解决了:

driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);

【讨论】:

【参考方案6】:

我确实遇到了这个问题,但下面的代码对我来说就像一个冠军。

    final ChromeOptions options = new ChromeOptions();
    options.addArguments("--window-size=1920,1080");
    options.addArguments("--allow-insecure-localhost");
    options.addArguments("--headless");
    options.addArguments("--disable-gpu");
    options.addArguments("--no-sandbox");
    DesiredCapabilities caps = DesiredCapabilities.chrome();
    caps.setCapability(ChromeOptions.CAPABILITY, options);
    caps.setCapability("acceptInsecureCerts", caps);
    WebDriver driver = new ChromeDriver(options);

【讨论】:

【参考方案7】:

我遇到了同样的问题,即 headless 不适用于某些网站和元素(显示空白页面内容、找不到元素等)。

这很可能是因为缺少 User-Agent 或窗口尺寸过小。添加以下参数:

"--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
"--window-size=1920x1080"

如果上述方法不起作用,还有另一种方法可以通过最小化并将窗口移动到用户看不到的位置来“模拟”无头模式。

这不会从任务栏中隐藏 chrome 任务,但 Chrome 选项卡本身仍将对用户隐藏。

只需使用以下参数:

var chromeOptions = new ChromeOptions();
chromeOptions.AddArguments(new List<string>()  "--window-size=1,1", "window-position=-2000,0" );  // This hides the chrome window

var chromeDriverService = ChromeDriverService.CreateDefaultService();
chromeDriverService.HideCommandPromptWindow = true;    // This is to hid the console.

ChromeDriver driver = new ChromeDriver(chromeDriverService, chromeOptions);
//driver.Manage().Window.Minimize(); //use this if the code above does not work
driver.Navigate().GoToUrl("https://google.com");

【讨论】:

【参考方案8】:

time.sleep(0.2) 为我修复了它。

我有同样的问题。在无头模式下,找不到一个 webElement,并且 selenium 抛出 NoSuchElementException 错误:消息:没有这样的元素:无法定位元素。

为我解决的问题是使用time.sleep(0.2) 上面的行添加了 0.2 秒的等待时间来定位此 webElement 并为我解决了它。

由于某种原因,在无头模式下加载此元素需要更多时间。

【讨论】:

以上是关于无法使用无头 chrome 在网页上定位元素的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 selenium 在 Web 地图应用程序中定位元素

解决网页元素无法定位(NoSuchElementException: Unable to locate element)的几种方法

selenium测试无法定位到网页元素,可能有以下原因

解决网页元素无法定位的几种方法

Chrome 浏览器无头问题:没有这样的元素:无法在 chrome://downloads/ 找到元素 [重复]

无法在 Selenium 和 Java 中使用 className 定位元素