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

时间:2017-12-25 12:43:10

标签: python beautifulsoup html-parsing

我有一个像这样的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>

我的目标是只获得一个字符串&#34; Bla bla bla Name bla bla bla ...名字bla bla&#34; 没有风格也没有。

为此,我使用该代码:

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> - 行包含<em>等标记,则BeautifulSoup不会返回文字。< / p>

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

编辑:

我想念的是包含标签的paragrapgh:

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

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

4 个答案:

答案 0 :(得分: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)

答案 1 :(得分: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()确保仅删除包含空格的行。

答案 2 :(得分: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.

答案 3 :(得分:0)

  

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

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

谢谢Martin !!!