如何仅使用BeautifulSoup从div中提取文本

问题描述 投票:1回答:4

我有一个包含DIV的HTML页面:

<div class="item-content">
    <p>Bla bla bla <em>Name</em> Ba bla bla.</p>
    <p>Bla bla bla.</p>
    <p> <a href="https://example.com/link.htm"><img src="/image.gif" height="620" width="620" /></a></p>
    <p><style> p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 18.0px...} </style></p>
    <p>Bla bla bla <em>Name</em> Ba bla bla.</p>
    <p>Bla bla bla.</p>
</div>

我的目标是获得一个只有“Bla bla bla Name bla bla bla ...字符串bla bla”的字符串。没有任何风格。

为此,我使用该代码:

from bs4 import BeautifulSoup

f = open('ogn2.html', 'r')

html_doc = f.read()

f.close()

soup = BeautifulSoup(html_doc, 'html.parser')

a = soup.find(attrs={"class": "item-content"})

b = a.find_all("p")

text = ""
a = 0

for p in b:
    a = a + 1
    print(a, p.string)
    if p.string and not p.style:
         text = text + " " + p.string

print(text)

使用这个我设法排除<a><style>但不幸的是,如果<p>-line包含像<em>这样的标签,BeautifulSoup不会返回文本。

我做错了什么?或者也许如何以更智能的方式实现这一目标(不是逐行阅读并再次连接它们)?

编辑:

我想念的是包含标签的段落:

<p>Bla bla bla <em>Name</em> Ba bla bla.</p>

因此,我希望的结果应该是整体的纯文本,中间没有任何附加标签。

python beautifulsoup html-parsing
4个回答
0
投票

如何使用过滤器,如下所示,

 def filter_tags(element):
   if element.parent.name in ['style']:
     return False
   return True


 texts = filter(filter_tags, soup.find(attrs={'class': 'item-content'}).find_all(text=True)) # This will return list of texts

 # You may apply join to concatenate.
 " ".join(texts)

0
投票

试试这个

entries = []
for p in b:
    if not p.style and p.text.strip():
        entries.append(p.text)

text = " ".join(entries)
print(text)

额外条件p.text.strip()确保删除仅包含空格的行。


0
投票

试试这个:

from bs4 import BeautifulSoup

content = """
<div class="item-content">
    <p>Bla bla bla <em>Name</em> Ba bla bla.</p>
    <p>Bla bla bla.</p>
    <p> <a href="https://example.com/link.htm"><img src="/image.gif" height="620" width="620" /></a></p>
    <p><style> p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 18.0px...} </style></p>
    <p>Bla bla bla <em>Name</em> Ba bla bla.</p>
    <p>Bla bla bla.</p>
</div>
"""
soup = BeautifulSoup(content,"lxml")
[item.extract() for item in soup.select("style")]
items = "".join([item.text for item in soup.select(".item-content p")])
print(items)

输出:

Bla bla bla Name Ba bla bla.Bla bla bla. Bla bla bla Name Ba bla bla.Bla bla bla.

0
投票

尝试使用p.getText()而不是p.string。 - Martin Schmelzer

这对我来说是最简单的方法!

谢谢马丁!

© www.soinside.com 2019 - 2024. All rights reserved.