使用BeautifulSoup基于内容值提取标签内容



我有一个Html文档,格式如下。

<p>&nbsp;&nbsp;&nbsp;1. Content of the paragraph <i> in italic </i> but not <b> strong </b> <a href="url">ignore</a>.</p>

我想提取段落标记的内容,包括斜体和粗体标记的内容但不包括锚点标记的内容。此外,可以忽略开头的数字。

预期输出为:该段内容用斜体表示,但不加粗。

最好的方法是什么?

此外,以下代码片段返回TypeError:"NoneType"类型的参数不可迭代

soup = BSoup(page)
for p in soup.findAll('p'):
    if '&nbsp;&nbsp;&nbsp;' in p.string:
        print p

谢谢你的建议。

您的代码失败,因为如果标记只有一个子级并且该子级是NavigableString ,则会设置tag.string

您可以通过提取a标签来实现您想要的:

from BeautifulSoup import BeautifulSoup
s = """<p>&nbsp;&nbsp;&nbsp;1. Content of the paragraph <i> in italic </i> but not <b> strong </b> <a href="url">ignore</a>.</p>"""
soup = BeautifulSoup(s, convertEntities=BeautifulSoup.HTML_ENTITIES)
for p in soup.findAll('p'):
    for a in p.findAll('a'):
        a.extract()
    print ''.join(p.findAll(text=True))

您在string方面遇到的问题是,如文档中所述,string仅可用:

如果标签只有一个子节点,并且该子节点是字符串

因此,在您的情况下,p.stringNone,您无法对其进行迭代。要访问标签内容,您必须使用p.contents(这是一个包含标签的列表)或p.text(这是删除了所有标签的字符串)。

在你的情况下,你可能正在寻找这样的东西:

>>> ''.join([str(e) for e in soup.p.contents
                    if not isinstance(e, BeautifulSoup.Tag)
                       or e.name != 'a'])
>>> '&nbsp;&nbsp;&nbsp;1. Content of the paragraph <i> in italic </i> but not <b> strong </b> .'

如果还需要删除"前缀,我会使用正则表达式从最终字符串中删除该部分。

我认为您只需要遍历p中的标记并收集所需的字符串。

使用lxml,可以使用XPath:

import lxml.html as LH
import re
content = '''
<p>&nbsp;&nbsp;&nbsp;1. Content of the paragraph <i> in italic </i> but not <b> strong </b> <a href="url">ignore</a>.</p>'''
doc = LH.fromstring(content)
ptext = ''.join(doc.xpath('//p/descendant-or-self::*[not(self::a)]/text()'))
pat = r'^.*d+.s*'
print(re.sub(pat,'',ptext))

收益率:

Content of the paragraph  in italic  but not  strong  .

http://www.crummy.com/software/BeautifulSoup/bs4/doc/#get-文本

如果只需要文档或标记的文本部分,可以使用get_text()方法。它以单个Unicode字符串的形式返回文档中或标记下的所有文本。(在上面链接中的文档中给出)

相关内容

  • 没有找到相关文章

最新更新