【问题标题】:Parsing HTML -- why does this document have to parsed by text and not by tags?解析 HTML——为什么这个文档必须通过文本而不是标签来解析?
【发布时间】:2021-01-14 06:01:36
【问题描述】:

我正在使用一个 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 中检查“cmets”,然后再次应用 BeautifulSoup。我有几个问题:

  1. 为什么找不到其他表?它们也是 HTML 标签(未注释掉),所以我很难理解其中的区别。

  2. comment_table 代码行的真正作用是什么?对我来说,它看起来像是在检查 text 属性,这些属性是 NavigableStrings,包含 supported_tables 中的一个元素?

  3. 如果我对上述内容是正确的,BeautifulSoup 如何简单地解析该文本块?是“魔法”还是该文本必须具有特定形式……因此,在这种情况下我们很幸运?

如果您需要更多信息来回答问题,请告诉我。谢谢!

【问题讨论】:

    标签: python html python-3.x beautifulsoup


    【解决方案1】:
    1. 虽然由于易于阅读格式化,它们可能看起来是页面源代码中的 HTML 标记,但它们实际上仍在注释块中。
    <!--
        <table>
        ...
    -->
    

    等价于

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

    想象一下,一行又一行的代码都被强制排成一行,不容易阅读,而且更容易将注释标签放在已经格式化的代码的顶部和底部。

    将“

    1. 这正是它正在做的事情。它在列表中找到包含项目的注释部分,然后将该部分解析为单独的 HTML 块(下一行)以查找表。

    2. 它从该行接收的文本是一段 HTML 代码,没有注释指示符,因此它会将其视为任何其他普通 HTML 代码

    【讨论】:

      【解决方案2】:

      不是这方面的专家,而是我的观察:

      1. 在浏览器中禁用 javascript 并再次检查(不要被您在页面上看到的内容弄糊涂了)。我认为大多数表格都被注释掉了。正如在另一个答案中提到的,这可能只是您难以观察评论的工作方式,但查找文本与supported_tables 值匹配的ID,您会看到这些表仍在包装cmets 内。

      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))
      
      

      CommentNavigableString 的一种。

      【讨论】:

      • 请评论这是怎么错的。他们仍然被注释掉。这将帮助我改进我的答案
      • 我投了赞成票。看起来您并没有错——不确定其他人可能看到了什么错误。
      猜你喜欢
      • 2011-04-29
      • 2014-11-03
      • 2012-05-26
      • 2018-02-07
      • 1970-01-01
      • 1970-01-01
      • 2020-12-31
      • 2012-06-23
      • 1970-01-01
      相关资源
      最近更新 更多