【发布时间】:2019-11-13 16:46:26
【问题描述】:
我需要循环并从一百万个网页中抓取一个元素(所有页面的类名相同)。我以以下(简化)方式设置了代码:
driver = webdriver.Firefox()
wait = WebDriverWait(driver, 10)
detail_dict = {}
for i in range(1000000):
url = f'http://www.cnappc.it/risultato.aspx?IDAssociato={i}&tipo=1#edit'
driver.get(url)
elem_detail = wait.until(expected_conditions
.presence_of_element_located((By.CLASS_NAME, 'content')))
detail_dict[i] = elem_detail.text
代码运行得相当顺利,当我中断内核进行检查时,我注意到i 和url 每次迭代都会增加。但是,驱动程序网页“卡”在第一个 URL 上,即http://www.cnappc.it/risultato.aspx?IDAssociato=0&tipo=1#edit,因此elem_detail.text 一遍又一遍地返回相同的字符串。似乎驱动程序网页无法跟上driver.get(url) 方法,尽管.get() 等待页面完全加载。
来自Selenium-Python/Getting Started:
driver.get 方法将导航到 URL 给出的页面。 WebDriver 将等待页面完全加载(即“onload”事件已触发),然后再将控制权返回给您的测试或脚本。
我为elem_detail 插入了预期条件,但无济于事。在driver.get(url) 之后设置time.sleep(2) 允许驱动程序网页更改和显示不同的内容,但是我将面临严重的减速。即使这样,页面也会不时卡住,字典值条目最终会不系统地重复。
您能否推荐一种不涉及time.sleep() 的稳健方法?
仅供参考:我将 selenium 与 geckodriver 一起使用。
【问题讨论】:
-
您已将超时设置为 10,尝试使用带有异常的 try catch 块,类似这样的尝试: # 等待所需的时间,或最多等待 10 秒以显示警报 WebDriverWait(driver, 10).until(cond.alert_is_present()) obj = driver.switch_to.alert except (NoAlertPresentException, TimeoutException) as py_ex: print("Alert not present") print (py_ex) print (py_ex.args) finally: driver.quit () ,这将帮助我们在每次迭代中找出问题所在。
-
感谢您的建议@redhatvicky。参考我发布的代码,我应该在
driver.get(url)命令之后插入你建议的try/except/finally 吗? -
每个代码都应该在 try 块内,这样预期的异常就会被捕获,我们可以看到在什么迭代中发生了什么,要么发生超时问题,要么发生任何其他异常跨度>
-
感谢@redhatvicky,我按照您的指示进行操作,结果如下:警报不存在\n 消息:\n ('', None, None)。我从来没有在网页上遇到过警报,并且我的代码运行时没有错误(除了每隔一段时间会出现一些 TimeoutException [通常在我遇到这样的错误之前发生数百次迭代])。
标签: python selenium-webdriver web-scraping webdriverwait expected-condition