我有一套不太有效的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” - 唯一一个格式正确的,这很奇怪。)
答案 0 :(得分:2)
另一种选择是纯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>]
答案 1 :(得分:0)
你试过了吗?
html.replace("<p>", "</p><p>")
然后:
html.replace("</p><p>", "<p>", 1)
清理第一个标签。
答案 2 :(得分:0)
如果每个p
标记都有自己的行,则可以从输入文本中删除空格(以防止末尾出现空白行),然后尝试:
搜索:(?<!(div|script|p)>)$
替换:</p>
如果该行未以开始或结束p
,div
或script
标记结束,则会向每个行结尾添加结束p
标记。要排除其他标签(例如table
等),请按相同方式添加标签:
(?<!(div|script|p|table|tr|td|th|section)>)$
等