Сегментированная прокрутка вниз страницы для проверки существования элемента - Python selenium, driver.execute_script - PullRequest
0 голосов
/ 25 апреля 2020

У меня головная боль проблемы: я пытаюсь нажать кнопку «загрузить больше» раздела навыков для страниц Linkedin. Но из-за разрешения экрана обычные решения, такие как action chains, которые позволяют мне прокручивать элемент, не работают.

Я написал об этом здесь (где мне посоветовали опубликовать другой вопрос) и здесь (где проблема оказалась в разрешении экрана).

В обоих сообщениях единственное решение, которое работало для меня, это команда типа driver.execute_script("window.scrollTo(0, 1800)") с указанными c координатами для указанной c Связанной страницы, на которую я ссылался в качестве примера. Проблема в том, что мне нужно l oop этой команды для нескольких профилей, поэтому заданная c координата на одной странице не работает для другого профиля, так как раздел навыков больше не находится в том же месте.

Я придумал решение, подобное этому, но оно кажется худшим из возможных:

try:
    ldmore=driver.find_element_by_xpath('//span[text()="Show more"]')
    ldmore.click()
except NoSuchElementException:
    driver.execute_script("scroll(0, 1600)")
    try:
        ldmore = driver.find_element_by_xpath('//span[text()="Show more"]')
        ldmore.click()
    except NoSuchElementException:
        driver.execute_script("scroll(0, 1800)")
        try:
            ldmore = driver.find_element_by_xpath('//span[text()="Show more"]')
            ldmore.click()
        except NoSuchElementException:
            driver.execute_script("scroll(0, 2000)")
            try:
                ldmore = driver.find_element_by_xpath('//span[text()="Show more"]')
                ldmore.click()
            except NoSuchElementException:
                driver.execute_script("scroll(0, 2200)")

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

РЕДАКТИРОВАТЬ: Многие решения используют строку ldmore = driver.find_element_by_xpath('//span[text()="Show more"]'), а затем некоторый синтаксис, который прокручивается до ldmore. Проблема в том, что я получаю Message: no such element: Unable to locate element при указании xpath до того, как страница будет прокручена до местоположения. Таким образом, код завершается ошибкой даже до того, как следующий синтаксис может перейти к ldmore.

Мой соответствующий код для вашей справки:

ChromeOptions = webdriver.ChromeOptions()
driver = webdriver.Chrome('C:\\Users\\Root\\Downloads\\chromedriver.exe')

driver.get('https://www.linkedin.com/login?fromSignIn=true&trk=guest_homepage-basic_nav-header-signin')
driver.maximize_window()

WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.NAME, "session_key"))).send_keys("EMAIL")
WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.NAME, "session_password"))).send_keys("PASSWORD")
WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.XPATH, "//button[@class='btn__primary--large from__button--floating']"))).click()

driver.get("https://www.linkedin.com/in/kate-yun-yi-wang-054977127/?originalSubdomain=hk")
driver.maximize_window()

ldmore=driver.find_element_by_xpath('//span[text()="Show more"]')

РЕДАКТИРОВАТЬ : Попытка решения с перерыв на конец страницы:

        looking_for_element = True
        ldmore = ''

        while looking_for_element:
            elements = driver.find_elements_by_xpath('//span[text()="Show more"]')

            if len(elements) > 0:
                ldmore = elements[0]
                sleep(5)
                ldmore.click()
                looking_for_element = False
            else:
                body = driver.find_element_by_css_selector('body')
                last_height = driver.execute_script("return document.body.scrollHeight")
                print(last_height)

                while True:

                    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
                    time.sleep(2)
                    new_height = driver.execute_script("return document.body.scrollHeight")

                    driver.execute_script(str(last_height))

                    if new_height == last_height:
                        break

                    body.send_keys(Keys.PAGE_DOWN)

1 Ответ

1 голос
/ 25 апреля 2020

Вместо прокрутки до заданной c координаты, вы сможете прокрутить до самого элемента

driver.execute_script("arguments[0].scrollIntoView();", ldmore)

и затем выполнить свой щелчок

ldmore.click()

, или вы можете используйте javascript, чтобы щелкать без прокрутки

driver.execute_script('arguments[0].click();', ldmore)

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

looking_for_element = True
ldmore = ''

while looking_for_element:
    elements = driver.find_elements_by_xpath('//span[text()="Show more"]')

    if len(elements) > 0:
        ldmore = elements[0]
        looking_for_element = False
    else:
        body = driver.find_element_by_css_selector('body')
        body.send_keys(Keys.PAGE_DOWN)

вам нужно будет добавить это, а также

from selenium.webdriver.common.keys import Keys

В конечном счете, вы захотите добавить некоторый код к этому l oop, чтобы проверить когда достигнут нижний край страницы и элемент не найден, есть способ выйти из l oop.

Вот способ выйти из l oop, если элемент не найден:

while looking_for_element:
    elements = driver.find_elements_by_xpath('//span[text()="Show more"]')

    if len(elements) > 0:
        ldmore = elements[0]
        looking_for_element = False
    else:
        global_copyright = driver.find_elements_by_css_selector('#globalfooter-copyright')

        if len(global_copyright) > 0:
            looking_for_element = False
        else:
            body = driver.find_element_by_css_selector('body')
            body.send_keys(Keys.PAGE_DOWN)

Это проверяет глобальное авторское право нижнего колонтитула, и как только этот элемент найден, l oop знает, что он достиг дна и не будет продолжать работу вниз страницы. Я мог бы использовать простой разрыв вместо изменения 'Looking_for_element' на False, но я думаю, что так будет удобнее читать.

...