2015-03-08 3 views
19

Мне удалось получить Python с Selenium и PhantomJS, чтобы перезагрузить динамически загружаемую бесконечную прокручиваемую страницу, как в примере ниже. Но как это можно изменить, чтобы вместо того, чтобы вручную устанавливать несколько перезагрузок, программа остановилась при достижении дна?Прокрутите вниз до бесконечной страницы с помощью PhantomJS в Python

reloads = 100000 #set the number of times to reload 
pause = 0 #initial time interval between reloads 
driver = webdriver.PhantomJS() 

# Load Twitter page and click to view all results 
driver.get(url) 
driver.find_element_by_link_text("All").click() 

# Keep reloading and pausing to reach the bottom 
for _ in range(reloads): 
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") 
    time.sleep(pause) 

text_file.write(driver.page_source.encode("utf-8")) 
text_file.close() 

ответ

28

Вы можете проверить, что прокрутка сделала что-либо на каждом шагу.

lastHeight = driver.execute_script("return document.body.scrollHeight") 
while True: 
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") 
    time.sleep(pause) 
    newHeight = driver.execute_script("return document.body.scrollHeight") 
    if newHeight == lastHeight: 
     break 
    lastHeight = newHeight 

Это использует статическое количество ожидания, которое плохо, потому что вы не хотите ждать ненужным, когда он закончится быстрее, и вы не хотите, что сценарий завершается преждевременно, когда динамическая нагрузка слишком медленно по какой-то причине ,

Поскольку на странице обычно загружается еще несколько элементов в список, вы можете проверить длину списка перед загрузкой и дождаться загрузки следующего элемента.

Для твиттера это может выглядеть следующим образом:

while True: 
    elemsCount = browser.execute_script("return document.querySelectorAll('.stream-items > li.stream-item').length") 

    browser.execute_script("window.scrollTo(0, document.body.scrollHeight);") 

    try: 
     WebDriverWait(browser, 20).until(
      lambda x: x.find_element_by_xpath(
       "//*[contains(@class,'stream-items')]/li[contains(@class,'stream-item')]["+str(elemsCount+1)+"]")) 
    except: 
     break 

Я использовал выражение XPath, поскольку PhantomJS 1.x есть ошибка иногда при использовании :nth-child() CSS селекторов.

Full version для справки.

+0

Не работает с PhantomJS, похоже. – textnet

+0

Также с веб-драйвером Firefox обе высоты печатаются как «Нет» – textnet

+0

Извините, забыли «возврат» и переместили спать в нужную позицию. –

Смежные вопросы