Python BeautifulSoup 提取元素之间的文本

2025-03-10 08:52:00
admin
原创
64
摘要:问题描述:我尝试从以下 HTML 中提取“这是我的文本”:<html> <body> <table> <td class="MYCLASS"> <!-- a comment --> <a hef...

问题描述:

我尝试从以下 HTML 中提取“这是我的文本”:

<html>
<body>
<table>
   <td class="MYCLASS">
      <!-- a comment -->
      <a hef="xy">Text</a>
      <p>something</p>
      THIS IS MY TEXT
      <p>something else</p>
      </br>
   </td>
</table>
</body>
</html>

我尝试过这种方法:

soup = BeautifulSoup(html)

for hit in soup.findAll(attrs={'class' : 'MYCLASS'}):
    print hit.text

但是我得到了所有嵌套标签之间的所有文本以及注释。

有人能帮助我从中去掉“这是我的文本”吗?


解决方案 1:

详细了解如何在解析树中BeautifulSoup导航。解析树已获得tagsNavigableStrings(因为这是文本)。示例

from BeautifulSoup import BeautifulSoup 
doc = ['<html><head><title>Page title</title></head>',
       '<body><p id="firstpara" align="center">This is paragraph <b>one</b>.',
       '<p id="secondpara" align="blah">This is paragraph <b>two</b>.',
       '</html>']
soup = BeautifulSoup(''.join(doc))

print soup.prettify()
# <html>
#  <head>
#   <title>
#    Page title
#   </title>
#  </head>
#  <body>
#   <p id="firstpara" align="center">
#    This is paragraph
#    <b>
#     one
#    </b>
#    .
#   </p>
#   <p id="secondpara" align="blah">
#    This is paragraph
#    <b>
#     two
#    </b>
#    .
#   </p>
#  </body>
# </html>

要向下移动解析树,您需要contentsstring

  • 内容是页面元素中包含的 Tag 和 NavigableString 对象的有序列表

  • 如果标签只有一个子节点,并且该子节点是字符串,则该子节点可用作 tag.string 以及 tag.contents[0]

对于上述情况,也就是说你可以得到

soup.b.string
# u'one'
soup.b.contents[0]
# u'one'

对于多个子节点,你可以有例如

pTag = soup.p
pTag.contents
# [u'This is paragraph ', <b>one</b>, u'.']

因此您可以在这里玩耍contents并获取您想要的索引的内容。

您还可以迭代标签,这是一个快捷方式。例如,

for i in soup.body:
    print i
# <p id="firstpara" align="center">This is paragraph <b>one</b>.</p>
# <p id="secondpara" align="blah">This is paragraph <b>two</b>.</p>

解决方案 2:

改用.children

from bs4 import NavigableString, Comment
print ''.join(unicode(child) for child in hit.children 
    if isinstance(child, NavigableString) and not isinstance(child, Comment))

是的,这有点像舞蹈。

输出:

>>> for hit in soup.findAll(attrs={'class' : 'MYCLASS'}):
...     print ''.join(unicode(child) for child in hit.children 
...         if isinstance(child, NavigableString) and not isinstance(child, Comment))
... 




      THIS IS MY TEXT

解决方案 3:

您可以使用.contents

>>> for hit in soup.findAll(attrs={'class' : 'MYCLASS'}):
...     print hit.contents[6].strip()
... 
THIS IS MY TEXT

解决方案 4:

使用您自己的汤对象:

soup.p.next_sibling.strip()
  1. 你直接用 * 抓取 <p> soup.p(这取决于它是解析树中的第一个 <p>)

  2. 然后在返回的next_sibling标签对象上使用soup.p,因为所需文本与 <p> 嵌套在解析树的同一级别

  3. .strip()只是一个 Python str 方法,用于删除前导和尾随空格

*否则只需使用您选择的过滤器即可找到元素

在解释器中它看起来像这样:

In [4]: soup.p
Out[4]: <p>something</p>

In [5]: type(soup.p)
Out[5]: bs4.element.Tag

In [6]: soup.p.next_sibling
Out[6]: u'
      THIS IS MY TEXT
      '

In [7]: type(soup.p.next_sibling)
Out[7]: bs4.element.NavigableString

In [8]: soup.p.next_sibling.strip()
Out[8]: u'THIS IS MY TEXT'

In [9]: type(soup.p.next_sibling.strip())
Out[9]: unicode

解决方案 5:

简短回答:soup.findAll('p')[0].next

真正的答案:您需要一个不变的参考点,从该参考点您可以到达您的目标。

您在对 Haidro 的回答的评论中提到,您想要的文本并不总是在同一个位置。找到它相对于某个元素位于同一位置的意义。然后弄清楚如何让 BeautifulSoup 按照该不变路径浏览解析树。

例如,在原始帖子中您提供的 HTML 中,目标字符串紧跟在第一个段落元素之后,并且该段落不为空。由于findAll('p')将找到段落元素,soup.find('p')[0]因此将是第一个段落元素。

在这种情况下您可以使用soup.find('p')soup.findAll('p')[n]更通用因为也许您的实际场景需要第 5 段或类似的内容。

fieldnext属性将是树中的下一个解析元素,包括子元素。因此soup.findAll('p')[0].next包含段落的文本,并将soup.findAll('p')[0].next.next在提供的 HTML 中返回您的目标。

解决方案 6:

soup = BeautifulSoup(html)
for hit in soup.findAll(attrs={'class' : 'MYCLASS'}):
  hit = hit.text.strip()
  print hit

这将打印:这是我的文本尝试一下..

解决方案 7:

BeautifulSoup 文档提供了使用 extract 方法从文档中删除对象的示例。以下示例的目的是从文档中删除所有注释:

删除元素

一旦获得了对元素的引用,就可以使用 extract 方法将其从树中删除。此代码将从
文档中删除所有注释:

from BeautifulSoup import BeautifulSoup, Comment
soup = BeautifulSoup("""1<!--The loneliest number-->
                    <a>2<!--Can be as bad as one--><b>3""")
comments = soup.findAll(text=lambda text:isinstance(text, Comment))
[comment.extract() for comment in comments]
print soup
# 1
# <a>2<b>3</b></a>
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   4008  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2751  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   86  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   97  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   85  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用