Невозможно очистить все данные из таблицы с отложенной загрузкой с помощью Selenium

Я пытаюсь извлечь три поля (player, logo, dkprice) из таблицы, расположенной в середине веб-страницы . Чтобы увидеть все данные в этой таблице, необходимо прокрутить ее вниз.

Я создал скрипт в selenium, который может прокручивать содержимое таблицы вниз, но может очищать только последние 16 результатов. Однако в таблице 240 элементов.

Моя цель — очистить все содержимое таблицы с помощью selenium, поскольку я уже успешно захватил содержимое с помощью модуля requests. Я хочу знать, почему даже после прокрутки вниз Selenium все еще не может проанализировать все содержимое этой таблицы.

Я добился успеха, используя модуль запросов:

import requests

link = 'https://fantasyteamadvice.com/api/user/get-ownership'

res = requests.post(link,json = {"sport":"mlb"})
for item in res.json()['ownership']:
    print(item['fullname'],item['team'],item['dkPrice'])

Скрипт, созданный с помощью Selenium, может анализировать только последние 16 элементов:

import time
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 selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

link = 'https://fantasyteamadvice.com/dfs/mlb/ownership'

def get_content(driver,link):
    driver.get(link)
    scroll_to_get_more(driver)
    for elem in WebDriverWait(driver,20).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,".ownership-table-container [class$='player-row']"))):
        player = elem.find_element(By.CSS_SELECTOR,"[data-testid='ownershipPlayer']").text
        logo = elem.find_element(By.CSS_SELECTOR,"[data-testid='ownershipPlayerTeam'] > img").get_attribute("alt")
        dkprice = elem.find_element(By.CSS_SELECTOR,"[data-testid='ownershipPlayerDkPrice']").text
        yield player,logo,dkprice


def scroll_to_get_more(driver):
    last_elem = ''
    while True:
        current_elem = WebDriverWait(driver,20).until(EC.visibility_of_element_located((By.CSS_SELECTOR,".ownership-table-container [class$='player-row']:last-child")))
        driver.execute_script("arguments[0].scrollIntoView();", current_elem)
        time.sleep(3) # wait for page to load new content
        if (last_elem == current_elem):
           break
        else:
           last_elem = current_elem


if __name__ == '__main__':
    driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
    try:
        for item in get_content(driver,link):
            print(item)
    finally:
        driver.quit()

Как я могу очистить все данные этой таблицы отложенной загрузки с помощью Selenium?

что не так с апи? и причина, по которой здесь только 16 элементов, заключается в том, что узлы удаляются/добавляются при прокрутке

GTK 28.07.2024 20:55

В API нет ничего плохого. Он работает нормально. Я хочу знать, как я могу очистить результаты с помощью Selenium.

SMTH 28.07.2024 22:27

как я уже сказал, узлы по какой-то причине удаляются/добавляются при прокрутке, возможно, понадобится какое-то хакерское решение, чтобы очистить их с помощью селена, это все для того, чтобы вы могли получить логотипы?

GTK 29.07.2024 00:51

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

SMTH 29.07.2024 05:49
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
122
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Все данные в таблице вы можете получить из ответа на следующий запрос:

Ответ принят как подходящий

Вы очищаете данные из таблицы после прокрутки вниз, проблема в том, что таблица загружается динамически, а HTML - это только то, что отображается. Таким образом, простая прокрутка вниз не приведет к просмотру всей таблицы. Вам нужно вытащить данные из таблицы (сохранить их), затем прокрутить, затем вытащить данные из таблицы (добавить их к тому, что уже сохранено), продолжение.

Итак, вот мой код, например:

import time
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 selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

link = 'https://fantasyteamadvice.com/dfs/mlb/ownership'

def get_content(driver):
    rows = WebDriverWait(driver,20).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,".ownership-table-container [class$='player-row']")))
    
    tempData = []
    for elem in rows:
        player = elem.find_element(By.CSS_SELECTOR,"[data-testid='ownershipPlayer']").text
        logo = elem.find_element(By.CSS_SELECTOR,"[data-testid='ownershipPlayerTeam'] > img").get_attribute("alt")
        dkprice = elem.find_element(By.CSS_SELECTOR,"[data-testid='ownershipPlayerDkPrice']").text

        tempData.append((player,logo,dkprice))
        
    return tempData
            
            
    
    


def scroll_to_get_more(driver):
    current_elem = WebDriverWait(driver,20).until(EC.visibility_of_element_located((By.CSS_SELECTOR,".ownership-table-container [class$='player-row']:last-child")))
    driver.execute_script("arguments[0].scrollIntoView();", current_elem)
    time.sleep(3) # wait for page to load new content


# To remove duplicates and maintain the order
def de_dup(data):
    dedup_data = []
    for x in data:
        if x not in dedup_data:
            dedup_data.append(x)
            
    return dedup_data


if __name__ == '__main__':
    driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
    driver.get(link)
    complete = False
    data = []
    while complete == False:
        current_data = data.copy()
        data += get_content(driver)
        data = de_dup(data)
        scroll_to_get_more(driver)
        
        # Once the code no longer adds new data, we know it's complete
        if len(current_data) == len(data):
            complete = True
            
    driver.close()
    
    for tup in data:
        print(tup)

Результат: 158 игроков.

('Carlos Santana', 'MIN logo', '$4200')
('Tommy Pham', 'CWS logo', '$3800')
('Jose Altuve', 'HOU logo', '$5300')
('Jd Martinez', 'NYM logo', '$4900')
('Salvador Perez', 'KAN logo', '$4900')
('Nathan Eovaldi', 'TEX logo', '$9300')
('Paul Goldschmidt', 'STL logo', '$4500')
('Christian Vazquez', 'MIN logo', '$2900')
('Nolan Arenado', 'STL logo', '$4100')
('Andrew Mccutchen', 'PIT logo', '$4200')
('Randal Grichuk', 'ARI logo', '$3200')
('Marcell Ozuna', 'ATL logo', '$5800')
('Jon Singleton', 'HOU logo', '$2700')
('Adam Duvall', 'ATL logo', '$3200')
('Jose Quintana', 'NYM logo', '$7400')
('Willson Contreras', 'STL logo', '$5100')
...
('Masataka Yoshida', 'BOS logo', '$3700')
('Jake Bloss', 'HOU logo', '$6600')
('Wyatt Langford', 'TEX logo', '$4200')
('Paul Skenes', 'PIT logo', '$10500')

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

На сайте используется window.innerHeight для установки высоты контейнера/видимых элементов. Вы можете заставить его отображать все, переопределив InnerHeight большим значением:

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


driver = webdriver.Chrome()
driver.get('https://fantasyteamadvice.com/dfs/mlb/ownership')
driver.execute_script('window.innerHeight = 100000;')

rows = WebDriverWait(driver, 30).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, 'div[data-testid = "ownershipPlayerRow"]'))) 
print(f'{len(rows) = }')

Это отличное продолжение.

chitown88 30.07.2024 09:49

Другие вопросы по теме