Как спарсить страницу, которая не сразу загружает все данные, на python?
Всем добрый день. Пишу парсер на Python, который парсит эту страницу https://www.flashscore.ru/match/6PN2l3Bc/#match-summary
(а именно время, в правом верхнем углу), но почему-то при запуске выводит None. Из-за чего это происходит? Может потому что код от страницы открывается в отдельном окне? P.S. Если нажать ctrl + shift + c, то откроется новое окно почему-то. Как спарсить время с этой страницы? https://www.flashscore.ru/match/6PN2l3Bc/#match-summary
Код:
from selenium import webdriver
from bs4 import BeautifulSoup
def main():
driver = webdriver.Chrome()
driver.implicitly_wait(30)
driver.get('https://www.flashscore.ru/match/6PN2l3Bc/#match-summary')
html = driver.page_source
soup = BeautifulSoup(html, 'lxml')
time = soup.find('div', class_="description__time mstat-date")
print(time)
if __name__ == '__main__':
main()
Вывод:
None
Если попробовать с requests спарсить, то выводит просто тег, но данные внутри тега он не видит:
from bs4 import BeautifulSoup
import requests
def get_html(url):
r = requests.get(url) # Получим метод Response
r.encoding = 'utf8'
return r.text # Вернем данные объекта text
def get_link(html):
soup = BeautifulSoup(html, 'lxml')
head = soup.find('div', id='utime')
print(head)
get_link(get_html('https://www.flashscore.ru/match/SvCBnstA/#match-summary'))
вывод:
<div class="description__time" id="utime"></div>
Ответы (1 шт):
Вы просто неправильно распарсили.
Вот верный вариант:
from selenium import webdriver
from bs4 import BeautifulSoup
def main():
driver = webdriver.Chrome()
driver.implicitly_wait(30)
driver.get('https://www.flashscore.ru/match/6PN2l3Bc/#match-summary')
html = driver.page_source
soup = BeautifulSoup(html, 'lxml')
time = soup.find('div', id="utime")
print(time.text)
if __name__ == '__main__':
main()
Поправка 1:
Заметка: здесь можно обойтись и только функционалом selenium-а.
В коде ниже, если после 30 секунд не появляется id="utime", selenium вызовет ошибку
from selenium import webdriver
def setup():
driver = webdriver.Chrome()
driver.implicitly_wait(30)
return driver
def main(driver):
driver.get("https://www.flashscore.ru/match/6PN2l3Bc/#match-summary")
utime = driver.find_element_by_id("utime")
return utime.text
if __name__ == "__main__":
driver = setup()
time = main(driver)
print(time)
Поправка 2: добавил функцию, для ожидания нужного id, включающего нужный тест
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 main(sec_wait):
driver = webdriver.Chrome()
wait = WebDriverWait(driver, sec_wait)
driver.get("https://www.flashscore.ru/match/6PN2l3Bc/#match-summary")
time = wait_to_find_id(driver, wait, "utime", ".")
print(time)
def wait_to_find_id(driver, wait, id_, text_to_find=""):
"""Finds an element by id 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.
"""
try:
element = wait.until(
EC.text_to_be_present_in_element((By.ID, id_), text_to_find)
)
return driver.find_element_by_id(id_).text
except TimeoutException:
driver.quit()
raise Exception(f"Element not found after {wait._timeout} sec of waiting")
except Exception as e:
driver.quit()
raise e
if __name__ == "__main__":
main(10)
