D
The problem was that there are also many hidden elements on the page and they go before the visible ones, so we need a visual check:
element.is_displayed() - reset the bool meaning if it's hidden. element or notYou also have to look for not only odds, but even if you look at the structure of html, it's gonna be clear that not all games are captured by only .odd.highlight, about half will be missed.This is the decision:import time
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def wait_to_find_by(driver, wait, value=None, find="", by=By.ID, text=True):
"""Finds an element by By object and an expectation for
checking if the given text is present in the specified element.
If no match was found within the specified time, an Exception is raised.
inputs:
driver - instance of the selenium.webdriver.some_class.
wait - instance of the selenium.webdriver.support.ui.WebDriverWait.
value[None] - The By object of the element to be found.
find[""] - the text that must be present in the element.
by[By.ID] - selenium.webdriver.common.by.By object.
text[True] - if False, then returns the element itself, otherwise - element.text.
"""
try:
element = wait.until(
EC.text_to_be_present_in_element((by, value), find)
)
element = driver.find_element(by=by, value=value)
if text:
return element.text
return element
except TimeoutException:
driver.quit()
raise Exception(f"Element not found after {wait._timeout} sec of waiting")
except Exception as e:
driver.quit()
raise e
driver = webdriver.Chrome()
driver.get('https://www.flashscore.ru/match/MmfXOTNn/#h2h;home')
wait = WebDriverWait(driver, 10)
time = wait_to_find_by(driver, wait, "utime", ".")
soup = BeautifulSoup(driver.page_source, 'lxml')
game = driver.find_element_by_css_selector(".highlight")
if game.is_displayed():
game.click()
Amendment 1:
Here comes the last five visible games on the page:import time
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def wait_to_find_by(driver, wait, value=None, find="", by=By.ID, text=True):
"""Finds an element by By object and an expectation for
checking if the given text is present in the specified element.
If no match was found within the specified time, an Exception is raised.
inputs:
driver - instance of the selenium.webdriver.some_class.
wait - instance of the selenium.webdriver.support.ui.WebDriverWait.
value[None] - The By object of the element to be found.
find[""] - the text that must be present in the element.
by[By.ID] - selenium.webdriver.common.by.By object.
text[True] - if False, then returns the element itself, otherwise - element.text.
"""
try:
element = wait.until(
EC.text_to_be_present_in_element((by, value), find)
)
element = driver.find_element(by=by, value=value)
if text:
return element.text
return element
except TimeoutException:
driver.quit()
raise Exception(f"Element not found after {wait._timeout} sec of waiting")
except Exception as e:
driver.quit()
raise e
driver = webdriver.Chrome()
driver.get('https://www.flashscore.ru/match/MmfXOTNn/#h2h;home')
wait = WebDriverWait(driver, 10)
time = wait_to_find_by(driver, wait, "utime", ".")
soup = BeautifulSoup(driver.page_source, 'lxml')
games = driver.find_elements_by_css_selector(".highlight")
displayed_games = []
for game in games:
if game.is_displayed():
displayed_games += [game]
for game in displayed_games[4:]:
game.click()