【问题标题】:Python Beautifulsoup getText() Concatenating Menu ItemsPython Beautifulsoup getText() 连接菜单项
【发布时间】:2017-02-01 00:57:57
【问题描述】:

我遇到过 BeautifulSoup 将文本连接在一起的情况——通常,我看不到其他网站导航的问题...

In [96]: nav_menu = """
<ul class="joomla-nav" id="topmenu">
<li id="current" class="selected item101"><a href="/" >Etusivu</a></li><li class="parent item107"><a href="/yritysesittely" >Yritys</a><ul><li class="item753"><a href="/yritys/yritysesittely" >Yritysesittely</a></li><li class="item755"><span class="separator">Kuvagalleria</span>
</li><li class="item754"><a href="/yritys/projektiesittely" >Projektiesittely</a></li></ul></li><li class="parent item108"><a class="tuotteetlinkki" href="/tuotteet" >Tuotteet</a><ul><li class="parent item317"><a href="/" >Rakentaminen</a><ul><li class="item110"><a href="/tuotteet/2012-02-17-10-36-23/mestaripihatto" >Mestaripihatto</a></li><li class="item111"><a href="/tuotteet/2012-02-17-10-36-23/rakennukset-ja-suunnittelu" >Rakentaminen ja suunnittelu</a></li><li class="item132"><a href="/tuotteet/2012-02-17-10-36-23/betonielementit" >Betonielementit</a></li><li class="item831"><a href="/tuotteet/2012-02-17-10-36-23/kattorakenteet-2" >Kattorakenteet</a></li><li class="item806"><a href="/tuotteet/2012-02-17-10-36-23/mestarikasvattamo" >Mestarikasvattamo</a></li><li class="item135"><a href="/tuotteet/2012-02-17-10-36-23/betoniritilat" >Betoniritilät</a></li></ul></li><li class="parent item318"><a href="#" >Pihattokalusteet ja -laitteet</a><ul><li class="item140"><a href="/tuotteet/2012-02-17-10-38-33/lypsy-ja-maidonkasittely" >GEA lypsy ja maidonkäsittely</a></li><li class="item270"><a href="/tuotteet/2012-02-17-10-38-33/pihattokalusteet" >GEA  pihattokalusteet</a></li><li class="item145"><a href="/tuotteet/2012-02-17-10-38-33/ruokintalaitteet" >GEA  ruokinta</a></li><li class="item146"><a href="/tuotteet/2012-02-17-10-38-33/lannanpoisto" >GEA lannanpoistolaitteet</a></li><li class="item147"><a href="/tuotteet/2012-02-17-10-38-33/varaosat-ja-tarvikkeet" >Varaosat ja tarvikkeet</a></li><li class="item141"><a href="/tuotteet/2012-02-17-10-38-33/merivirta-kalusteet" >Merivirta - kalusteet</a></li><li class="item785"><a href="/tuotteet/2012-02-17-10-38-33/2012-08-27-11-06-48" >Nautojen hyvinvointi</a></li></ul></li><li class="parent item814"><a href="#" >Karjatalous</a><ul><li class="item148"><a href="/tuotteet/2012-02-17-10-38-34/ilmanvaihto" >Ilmanvaihto</a></li><li class="item149"><a href="/tuotteet/2012-02-17-10-38-34/irtorehusiilot" >Irtorehusiilot</a></li><li class="item820"><a href="/tuotteet/2012-02-17-10-38-34/valaistus" >Valaistus</a></li><li class="item821"><a href="/tuotteet/2012-02-17-10-38-34/lietesaeilioen-verkkoaita" >Lietesäiliön verkkoaita</a></li></ul></li><li class="parent item320"><a href="/" >Lannankäsittely </a><ul><li class="item114"><a href="/tuotteet/2012-02-17-10-42-54/flygt-lietepumput" >Flygt-lietepumput</a></li></ul></li></ul></li><li class="item109"><a href="/jaelkimarkkinointilomake" >Jälkimarkkinointi</a></li><li class="item115"><a href="/yhteystiedot" >Yhteystiedot</a></li></ul>
"""

In [97]: nav_content = BeautifulSoup(nav_menu, "html.parser")

In [98]: nav_content.getText()
Out[98]: '\n\nEtusivuYritysYritysesittelyKuvagalleria\nProjektiesittelyTuotteetRakentaminenMestaripihattoRakentaminen ja suunnitteluBetonielementitKattorakenteetMestarikasvattamoBetoniritilätPihattokalusteet ja -laitteetGEA lypsy ja maidonkäsittelyGEA  pihattokalusteetGEA  ruokintaGEA lannanpoistolaitteetVaraosat ja tarvikkeetMerivirta - kalusteetNautojen hyvinvointiKarjatalousIlmanvaihtoIrtorehusiilotValaistusLietesäiliön verkkoaitaLannankäsittely Flygt-lietepumputJälkimarkkinointiYhteystiedot\n'

编辑:在评论之前,请注意函数getText() 返回一个连接字符串:'EtusivuYritysYritysesittely' 等等。然而,这些应该是单独的词:'Etusivu Yritys Yritysesittely';下面的代码正确地分割了每个单词。

根据Python Beautifulsoup get_text() not getting all text 的帖子,我也将解析器切换到lxml,但得到了类似的结果。

我发现BeautifulSoup Grab Visible Webpage Text 中概述的方法是一个不错的解决方法:

In [100]: def visible(element):
     ...:     if element.parent.name in ['style', 'script', '[document]', 'head', 'title', 'meta']:
     ...:         return False
     ...:     elif isinstance(element,bs4.element.Comment):
     ...:         return False
     ...:     return True
     ...:

In [101]: visible_texts = list(filter(visible, nav_content.findAll(text=True)))

In [102]: ' '.join(visible_texts)
Out[102]: '\n Etusivu Yritys Yritysesittely Kuvagalleria \n Projektiesittely Tuotteet Rakentaminen Mestaripihatto Rakentaminen ja suunnittelu Betonielementit Kattorakenteet Mestarikasvattamo Betoniritilät Pihattokalusteet ja -laitteet GEA lypsy ja maidonkäsittely GEA  pihattokalusteet GEA  ruokinta GEA lannanpoistolaitteet Varaosat ja tarvikkeet Merivirta - kalusteet Nautojen hyvinvointi Karjatalous Ilmanvaihto Irtorehusiilot Valaistus Lietesäiliön verkkoaita Lannankäsittely  Flygt-lietepumput Jälkimarkkinointi Yhteystiedot'

但我真的很难找出差异。当然我有read the documentation,但还没有弄清楚soup.findAll(text=True) 如何返回不同的结果。有那么一刻,我想知道这种行为是否是由于导航项目是芬兰语(字符串很奇怪!),但在将文本翻译成英文后,很明显这不是问题所在。所以迹象表明标记格式错误,但我真的很想在我承诺换出代码之前了解为什么......任何清晰度都非常感谢。

【问题讨论】:

  • 我不明白什么是问题?也许创建工作示例,以便我们可以运行它。并显示预期结果。
  • 你有关于soup.findAll(text=True)返回不一致结果的例子吗?
  • 我试过soup.getText()''.join(visible_texts)''.join(soup.findAll(text=True)),总是得到相同的字符串。我不知道问题出在哪里。我只看到一个区别 - 你使用空格 ' ' 来连接元素,它会在你的第二个结果中添加额外的空格。
  • 我做了一个快速编辑——上面的代码现在是一个工作示例。

标签: python beautifulsoup


【解决方案1】:

看了BS4源码:

def get_text(self, separator="", strip=False,
             types=(NavigableString, CData)):
    """
    Get all child strings, concatenated using the given separator.
    """
    return separator.join([s for s in self._all_strings(
                strip, types=types)])
getText = get_text

原来separator 参数是我遇到的行为背后的原因......像这样更改我的代码会返回预期的结果:

In [113]: nav_content.getText(separator=" ")
Out[113]: '\n \n Etusivu Yritys Yritysesittely Kuvagalleria \n Projektiesittely Tuotteet Rakentaminen Mestaripihatto Rakentaminen ja suunnittelu Betonielementit Kattorakenteet Mestarikasvattamo Betoniritilät Pihattokalusteet ja -laitteet GEA lypsy ja maidonkäsittely GEA  pihattokalusteet GEA  ruokinta GEA lannanpoistolaitteet Varaosat ja tarvikkeet Merivirta - kalusteet Nautojen hyvinvointi Karjatalous Ilmanvaihto Irtorehusiilot Valaistus Lietesäiliön verkkoaita Lannankäsittely  Flygt-lietepumput Jälkimarkkinointi Yhteystiedot \n'

【讨论】:

    【解决方案2】:
    get_text()
    

    如果您只想要文档或标签的文本部分,可以使用 get_text() 方法。它以单个 Unicode 字符串的形式返回文档中或标签下的所有文本

    find_all(text=True)
    

    返回一个文本列表,这些文本是相关上下文节点的后代。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 2020-01-27
      • 2021-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多