运行Python 2.7.8和Selenium 3.11.0(使用Chrome webdriver(,看到一些奇怪的行为。 tl/dr,尝试使用find_elements_by_css_selector
,它尊重像p:not(.ignore)
这样的选择器,但不是p:not(.ignore p)
(尽管它们都在真正的浏览器中工作。
我正在提供以下网页用于测试目的:
<html>
<title>Test</title>
<body>
<section class="ignore">
<p>Some content I don't want to pull.</p>
</section>
<p>Content I DO want to pull.</p>
<p>More important content.</p>
<p>Thanks for reading.</p>
<p class="also-ignore">(We CAN successfully ignore this one tho.)</p>
</body>
</html>
并使用以下脚本通过Selenium访问它:
#! /usr/bin/env python
from selenium import webdriver
if __name__ == '__main__':
driver = webdriver.Chrome()
try:
driver.get('http://localhost:8000/test.html')
elems = driver.find_elements_by_css_selector('p:not(.ignore p)')
for e in elems:
print e.text
finally:
driver.close()
上面抛出错误:
Traceback (most recent call last):
File "./test.py", line 10, in <module>
elems = driver.find_elements_by_css_selector('p:not(.ignore p)')
File "/Users/maiamccormick/code/seleniumtest/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 605, in find_elements_by_css_selector
return self.find_elements(by=By.CSS_SELECTOR, value=css_selector)
File "/Users/maiamccormick/code/seleniumtest/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 983, in find_elements
'value': value})['value'] or []
File "/Users/maiamccormick/code/seleniumtest/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 312, in execute
self.error_handler.check_response(response)
File "/Users/maiamccormick/code/seleniumtest/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: An invalid or illegal selector was specified
(Session info: chrome=65.0.3325.181)
(Driver info: chromedriver=2.37.544337 (8c0344a12e552148c185f7d5117db1f28d6c9e85),platform=Mac OS X 10.13.4 x86_64)
(选择器p:not(.ignore p)
确实可以在Chrome控制台中使用。
上面的 Python 代码使用 CSS 选择器p:not(.also-ignore)
(即忽略页面中的最后一个 <p>
元素(运行没有错误(并且具有预期的输出(,因此问题似乎不在于:not(...)
选择器本身。我被难住了——有人有想法吗?
来自 W3C 规范:
否定伪类 :not(X( 是一种函数表示法,采用 简单选择器(不包括否定伪类本身(作为 论点。它表示一个不由其表示的元素 论点。
这意味着不支持p:not(.ignore p)
。
现在,它在控制台中工作的原因是,速记$
被支持不同语法的JQuery
页面覆盖。
由于Selenium依赖于来自浏览器的CSS选择器(与document.querySelector
相同(,而不是来自JQuery,因此在这种情况下会出现例外。
请注意,您将通过在空白页 (about:blank( 中执行document.querySelector('p:not(.ignore p)')
或$('p:not(.ignore p)')
在控制台中获得异常。
如果你想使用JQuery选择器,那么使用JavaScript注入:
elms = driver.execute_script("return $('p:not(.ignore p)')")