Получение ошибки устаревшего элемента даже после определения элементов во второй раз - PullRequest
0 голосов
/ 19 июня 2020

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

from selenium import webdriver
driver = webdriver.Chrome(r'C:\Users\Hank\Desktop\chromedriver_win32\chromedriver.exe')
driver.get('https://steamcommunity.com/market/listings/440/Unusual%20Old%20Guadalajara')

import time

time.sleep(5)

from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait as wait
from selenium.webdriver.support.expected_conditions import presence_of_element_located
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import StaleElementReferenceException

action = ActionChains(driver)

next_button=wait(driver, 10).until(EC.element_to_be_clickable((By.ID,'searchResults_btn_next')))
next_button.click()
time.sleep(5)
back_button=wait(driver, 10).until(EC.element_to_be_clickable((By.ID,'searchResults_btn_prev')))
back_button.click()
#I run this code above to make sure the prices are in USD.

#Defining function to call later
def prices_and_effects():
    #Defining the list of images that I can hover to
    imgs = wait(driver, 5).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, 'img.market_listing_item_img.economy_item_hoverable')))
    for img in imgs:
        action.move_to_element(img).perform()
        #Hover to each element and grab the description inside
        print([my_element.text for my_element in wait(driver, 5).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "div.item_desc_description div.item_desc_descriptors#hover_item_descriptors div.descriptor")))])
    #Defining prices
    prices = driver.find_elements(By.CSS_SELECTOR, 'span.market_listing_price.market_listing_price_with_fee')
    for price in prices:
        #Printing each price out to the console
        print(price.text)

#Creating reference value to check against later after switching pages
ref_val=wait(driver, 10).until(EC.presence_of_element_located((By.ID,'searchResults_start'))).text

#While the button is able to be clicked, click it, make sure that the reference value has changed, and call the function. Repeat until all pages are scraped.

while next_button.get_attribute('class') == 'pagebtn':
    next_button.click()
    wait(driver, 10).until(lambda driver: wait(driver, 10).until(EC.presence_of_element_located((By.ID,'searchResults_start'))).text != ref_val)
    prices_and_effects()
    #Get the new reference value    
    ref_val = wait(driver, 10).until(EC.presence_of_element_located((By.ID, 'searchResults_start'))).text

Любая помощь будет принята с благодарностью, и, как всегда, направьте меня к соответствующему вопросу, если на него уже был дан ответ.

1 Ответ

1 голос
/ 19 июня 2020

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

#Defining function to call later
def prices_and_effects():
    action = ActionChains(driver)
    #Defining the list of images that I can hover to
    imgs = wait(driver, 5).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, 'img.market_listing_item_img.economy_item_hoverable')))
    for img in imgs:
        action.move_to_element(img).perform()
        #Hover to each element and grab the description inside
        print([my_element.text for my_element in wait(driver, 5).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "div.item_desc_description div.item_desc_descriptors#hover_item_descriptors div.descriptor")))])
    #Defining prices
    prices = driver.find_elements(By.CSS_SELECTOR, 'span.market_listing_price.market_listing_price_with_fee')
    for price in prices:
        #Printing each price out to the console
        print(price.text)
...