Как избежать StaleElementReferenceError при получении элементов с другой страницы? - PullRequest
0 голосов
/ 12 июня 2019

Я хочу получить все результаты гонки. Сайт показывает 50 строк / страницу. Я перехожу на следующую страницу (тот же URL с суффиксом # page-x), используя selenium, но я получаю ошибку StaleElementReferenceException всякий раз, когда пытаюсь найти элементы (ячейки таблицы = td) на следующей странице.

Я пытался закрыть драйвер между шагами, чтобы получить только один список элементов за раз. Я также пытался загрузить страницы отдельно с URL + суффиксом, но он загружается неправильно. Я пытался создать отдельные списки (сначала я хотел получить один большой список со всеми результатами).

from selenium import webdriver
url = "https://tickets.justrun.ca/quidchrono.php?a=qcResult&raceid=8444"

#The block under works well and I get a list of cells as intended.
driver = webdriver.Chrome()
driver.maximize_window()
driver.get(url)
elements = driver.find_elements_by_tag_name("td")
course = []
for i in range(len(elements)):
    course.append(elements[i].text)

to_2 = driver.find_element_by_link_text("2")
to_2.click()
print(driver.current_url)

#I'm trying similar code for the next chunk, but it doesn't work.
elements2 = driver.find_elements_by_tag_name("td")
print(len(elements2))
print(elements2[5].text)
course2 = []
for i in range(len(elements2)):
    course2.append(elements2[i].text)
driver.close()

Я ожидал бы новый список (курс 2) с результатами второй страницы, но я получаю ошибку устаревшего элемента. Когда я печатаю текущий URL, результат будет таким, как ожидалось. Когда я печатаю len (elements2), это тоже нормально. Похоже, проблема в том, что я пытаюсь получить текст элемента.

1 Ответ

1 голос
/ 12 июня 2019

Solution-1:

Использование BeautifulSoup и selenium, WebDriverWait ожидает определенного условия, прежде чем продолжить работу в коде. для более подробной информации о BeautifulSoup .

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup

url = "https://tickets.justrun.ca/quidchrono.php?a=qcResult&raceid=8444"
driver = webdriver.Chrome()

driver.get(url)

data = []
while True:
    course = []
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "tableJustrun")))

    page_soup = BeautifulSoup(driver.page_source, 'lxml')
    # get table data 
    tbody = page_soup.find("tbody",{"id":"searchResultBoxParticipants"})
    rows = tbody.find_all("tr")

    for row in rows:
        rowData = []
        for td in row.find_all("td"):
            rowData.append(td.text)

        course.append(rowData)
    data.append(course)

    try:
        pagination = driver.find_element_by_class_name("simple-pagination")
        next_page = pagination.find_element_by_link_text("Suivant")
        # iterate next page
        next_page.click()
    except Exception as e:
        break

print(data)

Раствор-2:

Использование библиотеки pandas.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pandas as pd

url = "https://tickets.justrun.ca/quidchrono.php?a=qcResult&raceid=8444"
driver = webdriver.Chrome()
driver.get(url)

data = []
while True:
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "tableJustrun")))
    tables = pd.read_html(driver.page_source)
    #append Participants table data
    data.append(tables[0])

    try:
        pagination = driver.find_element_by_class_name("simple-pagination")
        next_page = pagination.find_element_by_link_text("Suivant")
        # iterate next page
        next_page.click()
    except Exception as e:
        break

#Concat dataframe object
result = pd.concat(data)
print(result)
...