首先,我无法使用 python2.7.1 和 beautifulsoup4.3.2 重现 mac 结果,也就是说,我在所有系统上都得到了额外的分号。
简单的解决方法是 a) 使用严格有效的 HTML,或 b) 在 & 符号后添加一个空格。您可能无法更改源代码,如果您可以在 python 中解析并替换它们,您将不需要 BeautifulSoup ;)
所以问题是 BeautifulSoupHTMLParser 首先转换S&P500
为S&P500;
因为它假定P500
是字符名称而您只是忘记了分号。
然后它重新解析字符串并找到&P500;
. 现在它不能识别P500
为有效名称并将其转换&
为&
而不触及其余部分。
这是一个愚蠢的猴子补丁,只是为了证明我的观点。我不太了解 BeautifulSoup 的内部工作原理,无法提出适当的解决方案。
from bs4 import BeautifulSoup
from bs4.builder._htmlparser import BeautifulSoupHTMLParser
from bsp.dammit import EntitySubstitution
def handle_entityref(self, name):
character = EntitySubstitution.HTML_ENTITY_TO_CHARACTER.get(name)
if character is not None:
data = character
else:
# Previously was
# data = "&%s;" % name
data = "&%s" % name
self.handle_data(data)
html = '<td>S&P500</td>'
# Pre monkeypatching
# <td>S&P500;</td>
print(BeautifulSoup(html))
BeautifulSoupHTMLParser.handle_entityref = handle_entityref
# Post monkeypatching
# <td>S&P500</td>
print(BeautifulSoup(html))
希望更精通bs4的人能给你一个合适的解决方案,祝你好运。