【发布时间】:2021-05-08 05:54:33
【问题描述】:
网址是https://donstroy.com/full-search。在该页面上,其中有父 <div class="content"> 和 21 <div class="item">。当人类将鼠标悬停在<div class="content"> 上并向下滚动时,会动态出现多个新的<div class="item"> 元素。
我正在尝试通过 selenium 实现这个结果(出现新元素),但我只能得到前 21 个 <div class="item">。
我尝试了不同的方法在 selenium 中向下滚动,但没有一种方法导致出现新的 <div class="item"> 元素。下面是我的代码。当我在 Element Inspector 的控制台中以纯 javascript 运行它时,使用 scrollIntoView 的第一种方法工作正常(它会导致出现新元素)但仍然无法通过 selenium 工作。
import selenium.webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.common.action_chains import ActionChains
def parse_objs():
return driver.find_elements_by_xpath('//div[@class="item"]')
options = Options()
options.headless = True
driver = selenium.webdriver.Firefox(options=options)
driver.set_page_load_timeout(300) # yes, it may take up to multiple minutes to load the page so may need to wait long time, it's normal
driver.get('https://donstroy.com/full-search')
objs = parse_objs()
# Amount of object on initial page load
print('Initial load : %s' % len(objs)) # prints 21 as expected
# Method 1
driver.execute_script('arguments[0].scrollIntoView();', objs[-1])
objs = parse_objs()
print('Method 1 : %s' % len(objs)) # expected to increase but still prints 21
#The thing is that when running the same method in pure javascript in Element Inspector's console, it's working fine:
#var objs=document.getElementsByClassName('item');
#objs[20].scrollIntoView();
#after that, amount of objs (objs.length) increases to 41 so it should work in selenium but it does not!
# Method 2
actions = ActionChains(driver)
actions.move_to_element(objs[-1]).perform()
objs = parse_objs()
print('Method 2 : %s' % len(objs)) # expected to increase but still prints 21
# Method 3
objs_container=driver.find_element_by_xpath('//div[@class="content"]')
driver.execute_script('arguments[0].scrollTop = 300;', objs_container)
print('ScrollTop=%s' % driver.execute_script('return arguments[0].scrollTop', objs_container)) # always returns 0 no matter what value i try to apply for scrollTop in above command
objs = parse_objs()
print('Method 3 : %s' % len(objs)) # expected to increase but still prints 21
driver.quit()
【问题讨论】:
-
据我所见,我自己打开了 URL,页面加载需要很长时间。尝试使用一些 EC(预期条件),例如这里:stackoverflow.com/questions/59130200/…
-
基本上你必须在滚动后延迟抓取元素,因为它们需要加载。
-
感谢你们的 cmets 伙计们!是的,我在解释器交互模式下执行与代码中相同的步骤,其中我给每个步骤足够的时间,特别是我等待页面完全加载(我通过 driver.get 确认成功完成并执行 len(objs)得到 21)并且只有在那之后我才滚动,之后我在很长一段时间(几十分钟)内重复抓取多次,但它总是给出 21,仅此而已。