Я пытаюсь извлечь три поля (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?
В API нет ничего плохого. Он работает нормально. Я хочу знать, как я могу очистить результаты с помощью Selenium.
как я уже сказал, узлы по какой-то причине удаляются/добавляются при прокрутке, возможно, понадобится какое-то хакерское решение, чтобы очистить их с помощью селена, это все для того, чтобы вы могли получить логотипы?
Нет, меня не интересуют данные, доступные на этом сайте. Я просто хочу научиться очищать данные из таблицы после прокрутки вниз.
Все данные в таблице вы можете получить из ответа на следующий запрос:
Вы очищаете данные из таблицы после прокрутки вниз, проблема в том, что таблица загружается динамически, а 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) = }')
Это отличное продолжение.
что не так с апи? и причина, по которой здесь только 16 элементов, заключается в том, что узлы удаляются/добавляются при прокрутке