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

def player_stats(request, stat, numeric=False, s_index=False):
    """
    """

    supported_tables = ["totals", "per_minute", "per_poss", "advanced",
                        "playoffs_per_game", "playoffs_totals", "playoffs_per_minute",
                        "playoffs_per_poss", "playoffs_advanced"]

    if stat == "per_game":
        soup = BeautifulSoup(request.text, "html.parser")
        table = soup.find("table", id="per_game")
    elif stat in supported_tables:
        soup = BeautifulSoup(request.text, "html.parser")
        comment_table = soup.find(text=lambda x: isinstance(x, NavigableString) and stat in x)
        soup = BeautifulSoup(comment_table, "html.parser")
        table = soup.find("table", id=stat)
    else:
        raise TableNonExistent

Пример страницы, на которой это будет использоваться: https://www.basketball-reference.com/players/j/jamesle01.html

Если бы нужно было сделать soup.find_all("table"), была бы найдена только первая таблица. Похоже, что приведенный выше код проверяет наличие «комментариев» в HTML, а затем снова применяет BeautifulSoup к нему. У меня есть несколько вопросов:

  1. Почему не найдены другие таблицы? Они также являются тегами HTML (без комментариев), поэтому я изо всех сил пытаюсь понять разницу.

  2. Что на самом деле делает строка кода comment_table? Мне кажется, что он проверяет атрибуты text, которые являются NavigableString, которые содержат элемент в supported_tables?

  3. Если я прав относительно сказанного выше, как BeautifulSoup просто анализирует этот блок текста? Это «магия» или этот текст должен иметь определенную форму ... и, следовательно, нам в этом случае повезло?

Дайте мне знать, если вам понадобится дополнительная информация, чтобы ответить на вопросы. Благодаря!

0
Sam Dillard 14 Янв 2021 в 09:01

2 ответа

Лучший ответ
  1. Хотя они могут показаться HTML-тегами в источнике страницы из-за простоты форматирования для чтения, на самом деле они все еще находятся в комментированном блоке.
<!--
    <table>
    ...
-->

Эквивалентно

<!--<table>...-->

Представьте, что все строки и строки кода объединены в одну строку, их нелегко читать, и гораздо проще просто поместить теги комментариев поверх и под уже отформатированным кодом.

Может быть полезно подумать о «<-» как об идентификаторе блока, чтобы BeautifulSoup (и средства визуализации HTML) не увидели код между тегами для их визуализации.

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

  2. Текст, который он получает из этой строки, представляет собой блок HTML-кода без индикатора комментария, поэтому он обрабатывает его как любой другой нормальный HTML-код.

1
goalie1998 14 Янв 2021 в 06:33

Не эксперт в этом, но мои наблюдения:

  1. Отключите javascript в браузере и проверьте еще раз (чтобы вас не смущало то, что вы видите на странице). Я думаю, что большинство таблиц закомментированы. Как упоминалось в другом ответе, возможно, вам просто трудно наблюдать за тем, как работает комментирование, но ищите идентификаторы, текст которых соответствует значениям supported_tables, вы увидите, что эти таблицы все еще находятся в пределах комментариев.

  2. Строка comment_table в значительной степени делает то, что вы говорите. Я бы добавил, что supported_tables - это ожидаемый список закомментированных таблиц.

  3. Вы вернете bs4.element.Comment объект как comment_table, а не просто блок текста; который BeautifulSoup умеет разбирать. Вы можете проверить это с помощью:

elif stat in supported_tables:
    soup = BeautifulSoup(request.text, "html.parser")
    comment_table = soup.find(text=lambda x: isinstance(x, NavigableString) and stat in x)
    print(type(comment_table))

Comment - это тип NavigableString.

0
QHarr 14 Янв 2021 в 07:03
65714129