我有一组Web scraper,使用Selenium ChromeDriver在Python 3.6中运行。所有这些都完美无缺。
本周我将Selenium更新为v2.8,将ChromeDriver更新为v2.34。
紧接着,刮刀无法正常工作并在爬行的早期阶段坠毁。
我有一个sys.stdout
的实现,它输出到.txt和控制台,所以我开始注意到错误是这样的:
Message: no such frame
(Session info: chrome=63.0.3239.108)
(Driver info: chromedriver=2.34.522940
(1a76f96f66e3ca7b8e57d503b4dd3bccfba87af1),platform=Windows NT 10.0.15063 x86_64)
要么
Message: no such element: Unable to locate element:
{"method":"name","selector":"txtClave"}
(Session info: chrome=63.0.3239.108)
(Driver info: chromedriver=2.34.522940
(1a76f96f66e3ca7b8e57d503b4dd3bccfba87af1),platform=Windows NT 10.0.15063 x86_64)
Message: no such element: Unable to locate element:
{"method":"xpath","selector":"//*[@id="ctl00_cp_wz_ddlTarjetas"]/option[2]"}
(Session info: chrome=63.0.3239.108)
(Driver info: chromedriver=2.34.522940
(1a76f96f66e3ca7b8e57d503b4dd3bccfba87af1),platform=Windows NT 10.0.15063 x86_64)
Message: no such element: Unable to locate element:
{"method":"xpath","selector":"//*[@id="ctl00_cp_wz_ddlTarjetas"]/option[3]"}
(Session info: chrome=63.0.3239.108)
(Driver info: chromedriver=2.34.522940
(1a76f96f66e3ca7b8e57d503b4dd3bccfba87af1),platform=Windows NT 10.0.15063 x86_64)
Message: no such element: Unable to locate element:
{"method":"xpath","selector":"//*[@id="ctl00_cp_wz_ddlTarjetas"]/option[4]"}
(Session info: chrome=63.0.3239.108)
(Driver info: chromedriver=2.34.522940
(1a76f96f66e3ca7b8e57d503b4dd3bccfba87af1),platform=Windows NT 10.0.15063 x86_64)
这些往往是ChromeDriver崩溃的Windows消息,这是以前没有的:chromedriver.exe has stopped working
。
在查看Chrome窗口时,通过调试,我怀疑错误是由于应该让蜘蛛等待页面加载的行引起的,但是它不会等待,因此它无法找到元素。
导致错误的行的示例:
self.driver.find_element_by_name('txtUsuario').send_keys(user + Keys.RETURN)
self.driver.find_element_by_name('txtClave').send_keys(passwd + Keys.RETURN)
...
self.driver.switch_to.default_content()
self.driver.switch_to_frame('Fmenu')
self.driver.find_element_by_xpath(XPATH_POSICIONGLOBAL).click()
发现它太悲伤(并且基本上放弃)以失败过度添加显式等待到每个元素进行交互(可能因为我有一百多个?)。
我希望有人帮助我找出可能导致整套工作蜘蛛在这些新版本的ChromeDriver / Selenium中失败爬行的原因,并为此解决代码优雅且易于实施的解决方案。
例如,我尝试将implicitly_wait
附加到WebDriver会话中,但它根本就不起作用。
def __init__(self):
self.driver = webdriver.Chrome(PATH_WEBDRIVER)
self.driver.implicitly_wait(10)
最后,我使用IDLE一次运行两个失败的蜘蛛1行,它的工作原理!那么......为什么它不能在常规蜘蛛执行中工作?????
很多,非常感谢提前
让我试着逐一解决你的错误:
Message: no such frame
:如果您尝试在帧可用之前切换到该帧,则会出现此错误。在这种情况下,你需要诱导WebDriverWait
与匹配的expected_conditions
为frame
可用于切换。这是一个详细的Discussion
。请参阅A Better Approach to Switch Frames
部分。Message: no such element: Unable to locate element:
:如果你试图与之互动的WebElement
不是present
,visible
,clickable
或interactable
,那么这个错误就会出现。在这种情况下,你需要用匹配的WebDriverWait
诱导expected_conditions
。这是一个广泛使用的methods
列表:
class selenium.webdriver.support.expected_conditions.presence_of_element_located(locator)
class selenium.webdriver.support.expected_conditions.visibility_of_element_located(locator)
class selenium.webdriver.support.expected_conditions.element_to_be_clickable(locator)
chromedriver.exe has stopped working
:如果您的系统JDK
版本,Selenium
版本,ChromeDriver
版本和Chrome Browser
版本彼此不兼容且不同步,则此错误可能会出现。self.driver.find_element_by_name('txtUsuario').send_keys(user + Keys.RETURN)
:尝试按以下两个步骤分解这一行:
self.driver.find_element_by_name('txtUsuario').send_keys(user)
self.driver.find_element_by_name('txtUsuario').send_keys(Keys.RETURN)
self.driver.implicitly_wait(10)
:试着摆脱Implicit Wait
。为了保持领先的WebDriver
实例与尾随的Web Client
同步,我们必须使用WebDriverWait
即ExplicitWait
。但是你不应该把Implicit Wait
和ExplicitWait
混在一起。请参阅下面的Note
:注意:
Selenium Documentation
清楚地说 -WARNING: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example setting an implicit wait of 10 seconds and an explicit wait of 15 seconds, could cause a timeout to occur after 20 seconds.
如果要求只是Scraping
/ Crawling
网页,请使用Beautifulsoup
进行抓取/抓取并仅使用Selenium
浏览页面。