我尝试在python.org中爬行头横幅轮播以进行练习。我使用WebDriverWait
等待单击触发器后可见但无法正常工作的元素。这是我的代码。
# ChromeDriver
driver.get("https://www.python.org/")
hBannerNav = driver.find_elements_by_xpath(
'//ol[@class="flex-control-nav flex-control-paging"]/li/a')
for i in range(len(hBannerNav)):
print(hBannerNav[i].text)
hBannerNav[i].click()
try:
self.wait.until(EC.visibility_of_element_located(
(By.XPATH, '//ul[@class="slides menu"]/li[{}]'.format(i + 1))))
h1 = driver.find_element_by_xpath(
'//ul[@class="slides menu"]/li[{}]/div/h1'.format(i + 1))
print(h1.text)
# if add a sleep the crawler will work properly and smoothly,
# but I want to use WebDriverWait only.
# sleep(1)
except Exception as e:
print('error', e)
以下是日志:
# without sleep
1
Functions Defined
2
Compound Data Types
3
error Message:
4
Quick & Easy to Learn
5
All the Flow You’d Expect # wait for a long time but still crawl it
# use sleep
1
Functions Defined
2
Compound Data Types
3
Intuitive Interpretation
4
Quick & Easy to Learn
5
All the Flow You’d Expect
使用presence_of_all_elements_located
# the results by using
h1 = self.wait.until(EC.presence_of_all_elements_located(
(By.XPATH, '//ul[@class="slides menu"]/li[{}]/div/h1'.format(i + 1))))[0]
1
Functions Defined
2
Compound Data Types
3
4
5
答案 0 :(得分:2)
添加第二次等待-等待/div/h1
:
h1 = self.wait.until(EC.visibility_of_element_located(
(By.XPATH, '//ul[@class="slides menu"]/li[{}]/div/h1'.format(i + 1))))
在这种情况下,将其放在html中的时间要比其父项晚一些。
WebdriverWait.until()
确实返回匹配的元素,因此h1
将具有所需的值。
答案 1 :(得分:2)
我加载了您的代码并进行了旋转。您本质上做对了;问题是这个slides menu
元素有点奇怪。切换幻灯片时,有一个淡入淡出的效果需要一秒钟的时间。在这段时间内,感兴趣的li
/ h1
被视为“可见”,但滑动按钮无响应!在淡入淡出效果期间,尝试自己单击它们。什么都没发生。
在使用Selenium时,我经常遇到这些小的,意外的计时问题,并且解决方案因情况而异。
通常我会检查按钮是否可单击,但是这里的可单击性不是问题。
在这里,我通过等待上一张幻灯片的隐身性使其起作用:
for i in range(len(hBannerNav)):
print(hBannerNav[i].text)
hBannerNav[i].click()
# We don't wait if i == 0 because in that case, there's no previous slide
if i > 0:
WebDriverWait(driver, 3).until(
EC.invisibility_of_element_located((By.XPATH, '//ul[@class="slides menu"]/li[{}]'.format(i))))
h1 = driver.find_element_by_xpath(
'//ul[@class="slides menu"]/li[{}]/div/h1'.format(i + 1))
print(h1.text)
也许还有其他可能更好的方法来解决此计时问题,但希望这足以使您摆脱困境。