Я пытаюсь очистить URL-адреса с динамически выделяемой веб-страницы, которая требует непрерывной прокрутки для загрузки всего содержимого в DOM. Мой подход предполагает выполнение window.scrollTo(0, document.body.scrollHeight);
в цикле с использованием функции execute_script
Selenium. После каждой прокрутки я сравниваю количество URL-адресов, загруженных до и после прокрутки. Если количество URL-адресов не меняется, я предполагаю, что достигнут конец страницы, и прерываю цикл.
Однако сценарий предполагает, что весь контент загружен в DOM, хотя я знаю, что новый контент загружается в пределах заданного timeout
. Ниже мой код:
def _scroll_page_to_bottom(self, timeout: int): # Todo: Fix Bugs
while True:
urls_before_scroll = self.browser.find_elements(
By.XPATH, read_xpath(self.scrape_programs_urls.__name__, "programs_urls")
)
self.browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# Wait for new content to be loaded
try:
WebDriverWait(self.browser, timeout).until(
lambda _: len(self.browser.find_elements(
By.XPATH, read_xpath(self.scrape_programs_urls.__name__, "programs_urls"))
) > len(urls_before_scroll)
)
except TimeoutException:
# If no new content is loaded within the timeout, assume we've reached the end of the page
break
Может ли кто-нибудь угадать, что может быть причиной проблемы в приведенном выше коде?
Обновлено: я провел некоторую отладку и обнаружил, что проблема конкретно связана с функциональностью scroll
: когда я выполняю window.scrollTo(0, document.body.scrollHeight);
в console
браузере, страница также не прокручивается вниз, что объясняет, почему мой код не работает. Сайт, который я пытаюсь парсить: https://hackerone.com/opportunities/all/search
@vassiliev https://hackerone.com/opportunities/all/search
@vassiliev Я провел некоторую отладку и обнаружил, что проблема конкретно связана с функцией прокрутки: страница реагирует только на действия колесика мыши или клавишу со стрелкой вниз. я пытался смоделировать это, используя ActionChains
и даже pyautogui
, но ни один из них не сработал. Кроме того, мой код работал раньше (точнее, 2 дня), поэтому они, должно быть, изменили пользовательский интерфейс. В качестве примечания, когда я выполняю window.scrollTo(0, document.body.scrollHeight);
в консоли, страница не прокручивается вниз, что объясняет, почему мой код не работает.
Selenium не будет знать, когда прокрутка завершится или когда DOM будет повторно заполнен. После этого постарайтесь как следует поспать. И/или перехватывать исключения устаревших элементов во время итерации и повторно получать массив ссылок на элементы при их обнаружении.
@browsermator, я думаю, вы ошибаетесь, я уже использую WebDriverWait
, поэтому аргумент тайм-аута автоматически установит задержку и вызовет TimeoutException
, когда в течение заданного timeout
не загружается новый контент. Тем не менее, страница не прокручивается вниз с помощью javascript window.scrollTo(0, document.body.scrollHeight);
, поэтому проблема заключается в прокрутке.
Этот код ниже хорошо работает при прокрутке страницы вниз. Попробуйте встроить его в свой код:
ele = driver.find_element(By.XPATH, '//div[contains(@class,"Pane-module_u1-pane__content")]')
driver.execute_script('arguments[0].scrollIntoView(false);', ele)
Спасибо за ваш ответ! Но не могли бы вы объяснить и свой подход?
@binary 1) Я обнаружил, что элемент, который вы хотите продолжать прокручивать, - это <div class = "Pane-module_u1-pane__content__??? Pane-module_u1-pane__content--no-padding__-???">
, я использую функцию contain()
в xpath, чтобы найти элемент, чтобы предотвратить появление ??? часть меняется. 2) Я использую scrollIntoView()
вместо scrollTo()
, чтобы не указывать координаты. scrollIntoView(false)
означает прокрутку до конца этого элемента (равен scrollIntoView({block: "end", inline: "nearest"})
Спасибо, это работает, но по некоторым причинам он не работает с размером окна браузера по умолчанию, вместо этого он работает, когда я устанавливаю определенный размер окна для примера: driver.set_window_size(670, 670)
Можете ли вы опубликовать URL-адрес и сообщить нам, какой элемент вам нужно продолжать прокручивать?