首页 文章

使用beautifulsoup 4关闭格式错误的html中的<p>标签

提问于
浏览
0

我有一套不那么有效的html页面要刮掉 . 我需要的数据是“p”标签 . 但是,大多数都没有关闭:

<p>Bla-bla-bla
<p>bla bla
<p>more bla-bla
<p><span class="some_class">another bla</span>
<p>just some more bla bla bla
<div class="another_class"></div>
<script>
<p>here's some more </p>

所以当我执行搜索时,它会给我一个混乱的累积数据结果集:

In [2]: html='''
<p>Bla-bla-bla
<p>bla bla
<p>more bla-bla
<p><span class="some_class">another bla</span>
<p>just some more bla bla bla
<div class="another_class"></div>
<script>
<p>here's some more </p>'''

In [3]: from bs4 import BeautifulSoup

In [4]: soup = BeautifulSoup(html, "html.parser")

In [5]: p = soup.find_all('p')

In [6]: len(p)
Out[6]: 5

In [7]: p[0]
Out[7]: 
<p>Bla-bla-bla
<p>bla bla
<p>more bla-bla
<p><span class="some_class">another bla</span>
<p>just some more bla bla bla
<div class="another_class"></div>
<script></script></p></p></p></p></p>

In [8]: p[1]
Out[8]: 
<p>bla bla
<p>more bla-bla
<p><span class="some_class">another bla</span>
<p>just some more bla bla bla
<div class="another_class"></div>
<script></script></p></p></p></p>

In [9]: p[2]
Out[9]: 
<p>more bla-bla
<p><span class="some_class">another bla</span>
<p>just some more bla bla bla
<div class="another_class"></div>
<script></script></p></p></p>

我猜默认的'html.parser'只关闭输入字符串末尾的所有标签,无论有什么标签 . 在我的情况下,我希望解析器解析不太贪婪的标签,这样我就可以在一天结束时得到一个段落列表 . 是否有任何明显的解决方案,或者我应该处理这个累积的集合并通过例如后续的字符串或其他东西来清理它?

(汤也失去了最后一个“p” - 唯一一个格式正确的,这很奇怪 . )

3 回答

  • 0

    如果每个 p 标记都有自己的行,则可以从输入文本中删除空格(以防止末尾出现空行),然后尝试:

    搜索: (?<!(div|script|p)>)$

    替换: </p>

    如果该行不以打开或关闭 divscriptp 标记结束,那么将向每个行结尾添加一个结束 p 标记 . 要排除其他标签(例如 table 等),请以相同的方式添加它们:

    (?<!(div|script|p|table|tr|td|th|section)>)$

    等等

  • 0

    From bs4 docs

    另一种替代方法是纯Python html5lib解析器,它以Web浏览器的方式解析HTML .

    所以:

    pip install html5lib
    

    然后

    In [14]: soup = BeautifulSoup(html, "html5lib")
    
    In [15]: p = soup.find_all('p')
    
    In [17]: p[0]
    Out[17]: <p>Bla-bla-bla\n</p>
    

    然而,最后一段仍然丢失了:

    In [18]: len(p)
    Out[18]: 5
    
    In [19]: p2
    Out[19]: 
    [<p>Bla-bla-bla\n</p>,
     <p>bla bla\n</p>,
     <p>more bla-bla\n</p>,
     <p><span class="some_class">another bla</span>\n</p>,
     <p>just some more bla bla bla\n</p>]
    
  • 2

    你有没有尝试过:

    html.replace("<p>", "</p><p>")
    

    然后:

    html.replace("</p><p>", "<p>", 1)
    

    清理第一个标签 .

相关问题