Очистка таблицы с веб-страницы

Я пытаюсь очистить таблицу с веб-страницы с помощью Selenium и BeautifulSoup, но не знаю, как получить реальные данные с помощью BeautifulSoup.

веб-страница: https://leetify.com/app/match-details/5c438e85-c31c-443a-8257-5872d89e548c/details-general

Я попытался извлечь строки таблицы (тег <tr>), но когда я вызываю find_all, массив оказывается пустым.

Когда я проверяю элемент, я вижу несколько элементов с тегом tr, почему они не отображаются с помощью BeautifulSoup.find_all() ??

Я попытался извлечь строки таблицы (тег <tr>), но когда я вызываю find_all, массив оказывается пустым.

Код:

from selenium import webdriver
from bs4 import BeautifulSoup

driver = webdriver.Chrome()

driver.get("https://leetify.com/app/match-details/5c438e85-c31c-443a-8257-5872d89e548c/details-general")

html_source = driver.page_source

soup = BeautifulSoup(html_source, 'html.parser')

table = soup.find_all("tbody")
print(len(table))
for entry in table:
    print(entry)
    print("\n")
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
80
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

почему они не появляются с помощью BeautifulSoup.find_all() ??

после беглого взгляда кажется, что загрузка страницы занимает много времени.

Дело в том, что когда вы передаете driver.page_sourceBeautifulSoup, еще не весь HTML/CSS загружается.

Итак, решением было бы использовать явное ожидание:

Подождите, пока страница загрузится с помощью Selenium WebDriver для Python

или даже (менее рекомендуется):

from time import sleep
sleep(10)

но я не уверен на 100%, поскольку в настоящее время на моей машине не установлен Selenium


Однако я хотел бы принять совершенно другое решение:

Если вы посмотрите на сетевые вызовы вашего браузера (нажмите F12 в браузере, и откроется параметры разработчика), вы увидите, что данные (таблица), которые вы ищете, загружаются путем отправки запроса GET их API:

Конечная точка находится под:

https://api.leetify.com/api/games/5c438e85-c31c-443a-8257-5872d89e548c

который вы можете просмотреть прямо из вашего браузера.

Итак, вы можете напрямую использовать библиотеку запросов , чтобы отправить GET-запрос к указанной выше конечной точке, что будет намного эффективнее:

import requests
from pprint import pprint

response = requests.get('https://api.leetify.com/api/games/5c438e85-c31c-443a-8257-5872d89e548c')
data = response.json()


pprint(data)

Отпечатки (срезанные):

{'agents': [{'gameFinishedAt': '2024-07-06T07:10:02.000Z',
             'gameId': '5c438e85-c31c-443a-8257-5872d89e548c',
             'id': '63e38340-d1ae-4e19-b51c-e278e3325bbb',
             'model': 'customplayer_tm_balkan_variantk',
             'steam64Id': '76561198062922849',
             'teamNumber': 2},
            {'gameFinishedAt': '2024-07-06T07:10:02.000Z',
             'gameId': '5c438e85-c31c-443a-8257-5872d89e548c',
             'id': 'e10f9fc4-759d-493b-a17f-a85db2fcd09d',
             'model': 'customplayer_ctm_fbi_variantg',
             'steam64Id': '76561198062922849',
             'teamNumber': 3},

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

Вам нужно дать веб-странице время загрузиться. В настоящее время на большинстве веб-сайтов данные заполняются с помощью AJAX от клиента. Приведенный ниже код может помочь, но это не идеальный способ. Вы должны добавить логику ожидания, пока определенный элемент не станет видимым. См. https://selenium-python.readthedocs.io/waits.html

from selenium import webdriver
from bs4 import BeautifulSoup
import time

driver = webdriver.Chrome()

driver.get("https://leetify.com/app/match-details/5c438e85-c31c-443a-8257-5872d89e548c/details-general")

time.sleep(2)

html_source = driver.page_source

soup = BeautifulSoup(html_source, 'html.parser')

table = soup.find_all("tbody")
print(len(table))
for entry in table:
    print(entry)
    print("\n")

Вам не нужно использовать BeautifulSoup, поскольку все можно сделать с помощью модуля селена следующим образом:

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver import ChromeOptions
from selenium.webdriver.support.expected_conditions import presence_of_all_elements_located as POAEL

URL = "https://leetify.com/app/match-details/5c438e85-c31c-443a-8257-5872d89e548c/details-general"

options = ChromeOptions()
options.add_argument("--headless")

with webdriver.Chrome(options=options) as driver:
    driver.get(URL)
    wait = WebDriverWait(driver, 10)
    selector = By.CSS_SELECTOR, "table tr"
    for tr in wait.until(POAEL(selector)):
        print(tr.text)

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

Содержимое HTML на этой странице немного необычно: таблица содержит более одного элемента tbody, поэтому вам, вероятно, захочется это обработать. Код в этом ответе просто генерирует текст из всех/любых элементов tr в таблице, не принимая во внимание тело, откуда они пришли.

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