Прокрутите вниз до страницы с бесконечной загрузкой и щелкните ссылки, присутствующие на странице, при прокрутке вверх

#python #selenium #selenium-webdriver #xpath

#python #selenium #selenium-webdriver #xpath

Вопрос:

Я работаю над разработкой программы, используя selenium и python , путем нажатия на серию сообщений (n = 235), начиная с самого старого (# 235), вплоть до самого нового (# 1). Пока что у меня есть его версия, которая частично выполняет то, что должна делать. Я говорю частично, потому что некоторых задач, которые я хочу включить в эту программу, еще нет (и у меня возникли проблемы с написанием кода).
Итак, то, что у меня есть на данный момент, — это программа, которая прокручивает страницу до конца, находит самое старое сообщение и нажимает на него.

Вот код

 from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
import time

     

#for i in range(1000):
lenOfPage = driver.execute_script("window.scrollTo(0, document.body.scrollHeight);var lenOfPage=document.body.scrollHeight;return lenOfPage;")
match=False
while(match==False):
    lastCount = lenOfPage
    time.sleep(3)
    lenOfPage = driver.execute_script("window.scrollTo(0, document.body.scrollHeight);var lenOfPage=document.body.scrollHeight;return lenOfPage;")
    if lastCount==lenOfPage:
        match=True
time.sleep(5)
totalLink=235#len(driver.find_elements_by_xpath("//div//div[1]//div[2]//ul[1]//li[3]//a[1]//i[1]"))
for i in range (1,totalLink-1):
    linkxPath = "//div[" str(235-i 1) "]//div[1]//div[2]//ul[1]//li[3]//a[1]//i[1]"
    WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH,linkxPath))).click()
    driver.execute_script("arguments[0].scrollIntoView();", driver.find_element_by_xpath(linkxPath))
    #driver.find_element_by_xpath(linkxPath).click()
    driver.find_element_by_xpath("//span[@class='share-title']").click()
    #driver.refresh()
  

Проблемы:

  1. Мне не удалось включить функцию прокрутки вверх. Прямо сейчас, что я делаю, это обновляю страницу и прокручиваю ее до конца, затем нахожу самую старую запись и нажимаю на нее. Веб-страница, над которой я работаю, имеет такую особенность, что как только я нажимаю на более старую запись, эта запись становится новой (например, если я нажимаю на запись # 235, после обновления страницы она становится записью # 1).
  2. Я не смог придумать способ автоматизировать функцию щелчка, прямо сейчас у меня в коде есть 3 строки, в которых находятся элементы и щелчок по ним (не очень эффективно, потому что мне нужно обновить 235 сообщений, и я делаю это по 3 за раз). Просматривая элементы xpath, я заметил, что изменяется только одно число, но я не уверен, можно ли его изменить.

Элементы xpath:

 //div[235]//div[1]//div[2]//ul[1]//li[3]//a[1]//i[1]
//div[234]//div[1]//div[2]//ul[1]//li[3]//a[1]//i[1]
.
.
.
//div[1]//div[1]//div[2]//ul[1]//li[3]//a[1]//i[1]
  

Ошибка

 Traceback (most recent call last):
  File "/home/pi/Documents/Posh_Auto.py", line 39, in <module>
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH,linkxPath))).click()
  File "/usr/local/lib/python3.7/dist-packages/selenium/webdriver/remote/webelement.py", line 80, in click
    self._execute(Command.CLICK_ELEMENT)
  File "/usr/local/lib/python3.7/dist-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute
    return self._parent.execute(command, params)
  File "/usr/local/lib/python3.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python3.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <i class="icon share-gray"></i> is not clickable at point (860, 8). Other element would receive the click: <div aria-expanded="false" aria-haspopup="true" class="dropdown-toggle" data-toggle="dropdown">...</div>
  (Session info: chrome=78.0.3904.108)
  

Пожалуйста, дайте мне знать ваши мысли и комментарии.

Спасибо

Комментарии:

1. «//div[» i «]//div[1]//div[2] //ul[1] //li[3] //a[1] //i[1]» будет работать в цикле for.

2. На каком веб-сайте вы используете selenium?

Ответ №1:

 driver.get("https://poshmark.com/closet/alyssascott688?sort_by=added_descamp;just_in_closet=true")

# Waiting for Page to load successfully
WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.XPATH, "//img[@title='poshmark-logo']")))

# Since page is loading new elements after each scroll to bottom
# Get scroll height
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
    # Scroll down to bottom
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    # Wait to load page
    time.sleep(2)
    # Calculate new scroll height and compare with last scroll height
    new_height = driver.execute_script("return document.body.scrollHeight")
    if new_height == last_height:
        break
    last_height = new_height
shareLinks = driver.find_elements_by_xpath("//i[@class='icon share-gray']")

#Total such share link
print(len(shareLinks))

for i in range(1, len(shareLinks) 1):
    xpathLink = "(//i[@class='icon share-gray'])[" str(226-i 1) "]"
    #Creating Fresh elements so won't get stale element exception
    clickLink = driver.find_element_by_xpath(xpathLink)
    #Scroll to element and click
    driver.execute_script("arguments[0].scrollIntoView();", clickLink)
    driver.execute_script("arguments[0].click();", clickLink)
    #After clicking on Share Link, I am copying the link. You can perform any other action if you want
    WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.XPATH, "//i[@class='icon copy-white']"))).click()
    # To insure which link its clicking, I am printing link number
    print("copied : "   str(226-i 1))
    # Waiting for links to be clickable before go to next
    WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.XPATH, xpathLink)))
  

Комментарии:

1. Я думаю, вы должны сначала получить размер и повторить цикл столько раз и использовать индекс размера, чтобы каждый раз нажимать на //div[235] / div [1] //div [2] //ul [1] //li[3] //a [1] // i [1] и обновлять. LinkxPath всегда должен быть последним.

2. @Perro Я не понял вашего вопроса? Вы говорите, что он щелкнул в первый раз, но не смог щелкнуть второй раз и далее? Также, как вы упомянули, после каждого обновления, когда div [235] становится div [1], так что происходит с последующими разделениями? В идеале в таком случае ваш последний div снова станет div [235]. В таких сценариях, как предложено Arundeep, linkXpath всегда должен быть путем к div [235]. Пожалуйста, дайте мне знать, хотите ли вы после обновления всегда нажимать на последнюю ссылку?

3. @rahulrai извините, мой вопрос был неясен. Я обновил свой код в сообщении. Проблема в том, что он выполняет действие щелчка только один раз, затем я получаю сообщение об ошибке. Вы правы, моя идея состоит в том, чтобы найти элемент (например, 235) click, а затем перейти к следующему (например, 234), чтобы он в конечном итоге добрался до первого элемента (который находится вверху страницы). Как только все это будет сделано, обновите страницу.

4. Попробуйте обновленный код. Он щелкнет все div [235], div [234] ….div [1].

5. @rahulrai еще раз благодарю вас за комментарии и помощь. Основываясь на вашем предложении, я изменил свой код. В результате моя программа теперь прокручивается до конца страницы и нажимает на элементы div [235], div [234] и div [233], к сожалению, когда приходит время прокручивать вверх, чтобы найти следующий элемент div [232], я получаю ошибку и (пожалуйста, обратитесь к исходному сообщению). У вас есть какие-либо идеи, почему это происходит?