【问题标题】:How to only extract text from divs using BeatifulSoup如何使用 BeautifulSoup 仅从 div 中提取文本
【发布时间】:2018-06-06 17:09:37
【问题描述】:

我有一个包含这样的 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 ... Name 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)

使用它,我设法排除了&lt;a&gt;&lt;style&gt;,但不幸的是,如果&lt;p&gt; 行包含&lt;em&gt; 之类的标签,BeautifulSoup 不会返回文本。

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

编辑:

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

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

所以我想要的结果应该是整个纯文本,中间没有任何额外的标签。

【问题讨论】:

  • “很遗憾,BeautifulSoup 不返回文本,如果点”?什么点?
  • 任何 HTML 标签都需要使用code formatting。你能解释一下预期和实际的输出吗
  • 尝试p.getText() 而不是p.string
  • 嗨,马丁——我的圣诞英雄——成功了!完美!!!

标签: python beautifulsoup html-parsing


【解决方案1】:

尝试使用 p.getText() 代替 p.string。 ——马丁·施梅尔策

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

谢谢你马丁!!!

【讨论】:

  • 请注意 .getText 是已弃用界面的一部分 - 您确实应该养成在 BS4 中使用:.get_text 的习惯,因为它可能不会再存在了。
【解决方案2】:

试试这个:

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】:

    试试这个

    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() 确保删除仅包含空格的行。

    【讨论】:

      【解决方案4】:

      使用过滤器怎么样,如下所示,

       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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-12
        • 1970-01-01
        • 2022-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-12
        相关资源
        最近更新 更多