gpt4 book ai didi

python - 使用 Beautiful Soup Python 模块将标签替换为纯文本

转载 作者:行者123 更新时间:2023-12-05 02:25:12 26 4
gpt4 key购买 nike

我正在使用 Beautiful Soup从网页中提取“内容”。我知道有人问过这个 question之前,他们都指向 Beautiful Soup,这就是我开始使用它的方式。

我能够成功获取大部分内容,但我遇到了一些挑战,这些标签是内容的一部分。 (我从一个基本策略开始:如果一个节点中有超过 x 个字符,那么它就是内容)。下面以html代码为例:

<div id="abc">
some long text goes <a href="/"> here </a> and hopefully it
will get picked up by the parser as content
</div>

results = soup.findAll(text=lambda(x): len(x) > 20)

当我使用上面的代码获取长文本时,它在标签处中断(识别的文本将从'and hopefully..'开始)。所以我尝试用纯文本替换标签,如下所示:

anchors = soup.findAll('a')

for a in anchors:
a.replaceWith('plain text')

上面的代码不起作用,因为 Beautiful Soup 将字符串作为 NavigableString 插入,当我将 findAll 与 len(x) > 20 一起使用时会导致同样的问题。我可以先使用正则表达式将 html 解析为纯文本,清除所有不需要的标签,然后调用 Beautiful Soup。但我想避免两次处理相同的内容——我正在尝试解析这些页面,以便我可以显示给定链接的内容片段(非常像 Facebook 分享)——如果一切都用 Beautiful Soup 完成,我想它会更快。

所以我的问题是:有没有一种方法可以使用 Beautiful Soup 来“清除标签”并将它们替换为“纯文本”。如果没有,最好的方法是什么?

感谢您的建议!

更新 Alex 的代码在示例中运行良好。我还尝试了各种边缘情况,它们都运行良好(经过以下修改)。所以我在现实生活中的网站上试了一下,但遇到了让我困惑的问题。

import urllib
from BeautifulSoup import BeautifulSoup

page = urllib.urlopen('http://www.engadget.com/2010/01/12/kingston-ssdnow-v-dips-to-30gb-size-lower-price/')

anchors = soup.findAll('a')
i = 0
for a in anchors:
print str(i) + ":" + str(a)
for a in anchors:
if (a.string is None): a.string = ''
if (a.previousSibling is None and a.nextSibling is None):
a.previousSibling = a.string
elif (a.previousSibling is None and a.nextSibling is not None):
a.nextSibling.replaceWith(a.string + a.nextSibling)
elif (a.previousSibling is not None and a.nextSibling is None):
a.previousSibling.replaceWith(a.previousSibling + a.string)
else:
a.previousSibling.replaceWith(a.previousSibling + a.string + a.nextSibling)
a.nextSibling.extract()
i = i+1

当我运行上面的代码时,出现以下错误:

0:<a href="http://www.switched.com/category/ces-2010">Stay up to date with 
Switched's CES 2010 coverage</a>
Traceback (most recent call last):
File "parselink.py", line 44, in <module>
a.previousSibling.replaceWith(a.previousSibling + a.string + a.nextSibling)
TypeError: unsupported operand type(s) for +: 'Tag' and 'NavigableString'

当我查看 HTML 代码时,'Stay up to date..' 没有任何 previous sibling 姐妹(我不知道 previous sibling 姐妹是如何工作的,直到我看到 Alex 的代码并且根据我的测试它看起来像是在寻找标记前的“文本”)。所以,如果没有 previous sibling 姐妹,我很惊讶它没有通过 a.previousSibling is None 和 a;nextSibling is None 的 if 逻辑。

你能告诉我我做错了什么吗?

-ecognium

最佳答案

适用于您的特定示例的方法是:

from BeautifulSoup import BeautifulSoup

ht = '''
<div id="abc">
some long text goes <a href="/"> here </a> and hopefully it
will get picked up by the parser as content
</div>
'''
soup = BeautifulSoup(ht)

anchors = soup.findAll('a')
for a in anchors:
a.previousSibling.replaceWith(a.previousSibling + a.string)

results = soup.findAll(text=lambda(x): len(x) > 20)

print results

发射

$ python bs.py
[u'\n some long text goes here ', u' and hopefully it \n will get picked up by the parser as content\n']

当然,您可能需要多加注意,即,如果没有 a.string 怎么办? ,或者如果 a.previousSiblingNone -- 你需要合适的 if声明来处理这种极端情况。但我希望这个总体思路可以帮助你。 (事实上​​ ,如果 next 兄弟是一个字符串,您可能希望合并它 - 不确定它如何与您的启发式算法一起使用 len(x) > 20 ,但例如说您有两个 9 个字符的字符串,<a> 中间包含一个 5 个字符的字符串,也许你想把这批货当作“23 个字符的字符串”?我不知道,因为我不知道了解启发式的动机)。

我想除了<a>您还需要删除其他标签,例如 <b><strong> , 也许 <p>和/或 <br> , ETC...?我想这也取决于您的启发式背后的实际想法是什么!

关于python - 使用 Beautiful Soup Python 模块将标签替换为纯文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2061718/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com