【问题标题】:Why this find_all method (BeautifulSoup4) won't return all URLs properly?为什么这个 find_all 方法 (BeautifulSoup4) 不能正确返回所有 URL?
【发布时间】:2021-09-19 19:27:18
【问题描述】:

我在使用 BeautifulSoup4 时遇到问题。

我正在尝试在特定 div 下的某个 html 页面 (https://www.gov.br/pt-br/servicos/infrabr) 上查找每个链接,这是我的代码:

for a in soup.find(class_='col-servico').find_all(href = True):
    print(a['href'])

这是我感兴趣的 html 块(它在 div class=col-servico 内部):

<div class="servico_fieldset_outras_conteudo">
   <p style="text-align: justify; ">Agora, o Sistema Eletrônico do Serviço de Informação (e-SIC) está integrado 
ao&nbsp;<span><a href="http://fala.BR" class="linkified" target="_blank">Fala.BR</a></span>.
 Desenvolvida .</p>
   <p style="text-align: justify; ">Em conformidade com
 a&nbsp;
<span><a class="external-link" 
href="http://www.planalto.gov.br/ccivil_03/_ato2011-2014/2011/lei/l12527.htm" target="_blank" title="" 
data-tippreview-enabled="false" data-tippreview-image="" data-tippreview-title="">

你可以看到这个块有两个'a'标签:

<span><a href="http://fala.BR" class="linkified" target="_blank">Fala.BR</a></span>

<span><a class="external-link" 
href="http://www.planalto.gov.br/ccivil_03/_ato2011-2014/2011/lei/l12527.htm" target="_blank" title="" 
data-tippreview-enabled="false" data-tippreview-image="" data-tippreview-title="">

但我的结果是只带了一个:

http://www.planalto.gov.br/ccivil_03/_ato2011-2014/2011/lei/l12527.htm

如您所见,它只返回“planalto.gov.br”网址,而不是“fala.BR”网址。我看不出这两个“a”标签之间有什么区别,我不知道为什么它没有返回第一个链接。有人可以帮帮我吗?

【问题讨论】:

    标签: python html beautifulsoup


    【解决方案1】:

    我认为有几个问题。首先,在您提供的链接中,给定的 div 中没有 fala br 的 href。您可以手动检查:

    import httpx
    
    res = httpx.get("https://www.gov.br/pt-br/servicos/infrabr")
    soup = BeautifulSoup(res.text)
    
    print(soup.find(class_="col-servico").prettify())
    

    如果我们改用您发布的 sn-p,我们会得到 fala BR href:

    html = """
    <div class="servico_fieldset_outras_conteudo">
       <p style="text-align: justify; ">Agora, o Sistema Eletrônico do Serviço de Informação (e-SIC) está integrado 
    ao&nbsp;<span><a href="http://fala.BR" class="linkified" target="_blank">Fala.BR</a></span>.
     Desenvolvida .</p>
       <p style="text-align: justify; ">Em conformidade com
     a&nbsp;
    <span><a class="external-link" 
    href="http://www.planalto.gov.br/ccivil_03/_ato2011-2014/2011/lei/l12527.htm" target="_blank" title="" 
    data-tippreview-enabled="false" data-tippreview-image="" data-tippreview-title="">
    """
    
    soup = BeautifulSoup(html)
    
    for a in soup.find(class_="servico_fieldset_outras_conteudo").find_all(href=True):
        print(a["href"])
    
    # Returns:
    # http://fala.BR
    # http://www.planalto.gov.br/ccivil_03/_ato2011-2014/2011/lei/l12527.htm
    

    也许只是检查一下您在处理过程中是否使用了正确的 HTML

    【讨论】:

    • 你完全正确。但我很困惑。如果我在浏览器上打开页面,我可以看到 Fala.BR 作为“a”标签,但使用您的代码,我确实只得到了文本“Fala.BR”:

      Agora, o Sistema Eletrônico do Serviço de Informação (e-SIC) está integrado aoFala.BR

    • 之后似乎有些 javascript 正在处理链接? Fala.BR 有“链接”类,它看起来像是某种库
    【解决方案2】:

    在某些 cmets 中也有一些 'col-servico' 的匹配项,并且 cmets 不是标记,因此当您调用 find_all 时会出现错误。 代码在这里

    from bs4 import BeautifulSoup, Tag
    
    [...]
    
    for div in soup.find(class_='col-servico'):
        if isinstance(div, Tag):
            for tag in div.find_all(href=True):
                print(tag['href'])
    

    输出

    #
    #
    #
    #
    http://www.planalto.gov.br/ccivil_03/_ato2011-2014/2011/lei/l12527.htm
    http://www.planalto.gov.br/ccivil_03/_ato2015-2018/2017/lei/l13460.htm
    https://www.gov.br/pt-br/orgaos/ministerio-da-infraestrutura
    

    【讨论】:

    • 我发布的那个 html 在 class='col-servico' 的 div 中,这就是我使用 '.find' 的原因。然后我使用 .find_all 来获取这个 div 中的所有链接。我测试了您的代码,但正如预期的那样,它什么也没给我。因为没有具有 class='col-servico' 的元素具有 href。
    • 一般来说,不要忘记在你的问题中添加错误信息:)
    • 起初我没有收到错误,只是空白。但现在我有: NameError: name 'tag' is not defined。我没有找到 col-servico 的任何其他匹配项,甚至在 cmets 中也没有
    • 是的,我得到了这个输出。它缺少“fala.br”链接
    • 我查了源码,没有这个链接,[no links with fala.br]。什么是完整链接?你确定这不在某些javascript函数中吗? bs4 不解析 js
    猜你喜欢
    • 2018-03-04
    • 2015-10-05
    • 2019-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 1970-01-01
    • 2013-10-14
    相关资源
    最近更新 更多