为了账号安全,请及时绑定邮箱和手机立即绑定

Python Webscraping beautifulsoup 避免在 find_all()

Python Webscraping beautifulsoup 避免在 find_all()

隔江千里 2022-10-25 16:10:56
我正在使用 Beautifulsoup 在 Python 中进行网络抓取。我正在尝试以粗体或斜体或两者提取文本。考虑以下 HTML 片段。<div>  <b>     <i>      HelloWorld   </i>  </b></div>如果我使用 command sp.find_all(['i', 'b']),可以理解,我会得到两个结果,一个对应于粗体,另一个对应于斜体。IE['<b><i>HelloWorld</i></b>', '<i>HelloWorld</i>']我的问题是,有没有办法唯一地提取它并获取标签?我想要的输出是这样的 -标签:文本 - HelloWorld,标签名:[b,i]请注意,比较文本并剔除文本的非唯一出现不是一个可行的选择,因为我可能在文本中重复了很多次“HelloWorld”,而我想将其提取出来。谢谢!
查看完整描述

2 回答

?
元芳怎么了

TA贡献1798条经验 获得超7个赞

XPath是查找同时具有它们的祖先的节点的最自然的<b>方法<i>

//node()[ancestor::i or ancestor::b]

node()您可以根据情况使用text()查找文本节点或*查找元素来代替。这不会选择任何重复项,也不关心以什么顺序<i>嵌套<b>

这个想法的问题是 BeautifulSoup 不支持 XPath。出于这个原因,我会使用 lxml 而不是 BeautifulSoup进行网络抓取。


查看完整回答
反对 回复 2022-10-25
?
婷婷同学_

TA贡献1844条经验 获得超8个赞

我会说它没有明确定义。如果你有<b>foo<i>bar</i><b>(它可能更复杂)怎么办?


无论如何,我会说你必须实现递归。


这是一个例子:


import bs4


html = """

<div>

  <b> 

    <i>

      HelloWorld

   </i>

  </b>

</div>

"""


def recursive_find(soup):

    for child in soup.children:

        result = child.find_all(['i', 'b'], recursive=False)

        if result:

            if len(result) == 1:

                result_s_result = result[0].find_all(['i', 'b'], recursive=False)

                if len(result_s_result) == 1:

                    print(result_s_result[0].contents)

            else:

                print(result)

        else:

            recursive_find(child)


oneline_html = "".join(line.strip() for line in html.split("\n"))


soup = bs4.BeautifulSoup(oneline_html, 'html.parser')


recursive_find(soup)


查看完整回答
反对 回复 2022-10-25
  • 2 回答
  • 0 关注
  • 70 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信