Python BeautifulSoup & 问题 Mac 与 Linux Ubuntu

标签 python html linux macos beautifulsoup

我读到 BeautifulSoup 存在与符号 (&) 的问题,这在 HTML 中并不严格正确,但仍能被大多数浏览器正确解释。然而奇怪的是,我在 Mac 系统和 Ubuntu 系统上得到不同的行为,两者都使用 bs4 版本 4.3.2:

html='<td>S&P500</td>'
s=bs4.BeautifulSoup(html)

在Ubuntu系统上s等于:

<td>S&amp;P500;</td>

注意最后添加的分号,这是一个真正的问题

在mac系统上:

<html><head></head><body>S&amp;P500</body></html>

不用管 html/head/body 标签,我可以处理它,但请注意这次正确解释了标准普尔 500 指数,没有添加“;”。

知道发生了什么事吗?如何在不诉诸丑陋黑客的情况下制作跨平台代码?非常感谢,

最佳答案

首先,我无法使用 python2.7.1 和 beautifulsoup4.3.2 重现 mac 结果,也就是说我在所有系统上都得到了额外的分号。

简单的解决方法是 a) 使用严格有效的 HTML,或 b) 在 & 符号后添加一个空格。您可能无法更改源代码,如果您可以在 python 中解析并替换它们,您就不需要 BeautifulSoup ;)

所以问题是 BeautifulSoupHTMLParser 首先将 S&P500 转换为 S&P500; 因为它假定 P500 是角色名称而你只是忘记了分号。

然后它重新解析字符串并找到 &P500;。现在它不会将 P500 识别为有效名称并将 & 转换为 & 而不触及其余部分。

这是一个愚蠢的 monkeypatch 只是为了证明我的观点。我不太了解 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&amp;P500;</td>
print(BeautifulSoup(html))

BeautifulSoupHTMLParser.handle_entityref = handle_entityref

# Post monkeypatching    
# <td>S&amp;P500</td>
print(BeautifulSoup(html))

希望更精通bs4的人能给你一个合适的解决方案,祝你好运。

关于Python BeautifulSoup & 问题 Mac 与 Linux Ubuntu,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19234880/

相关文章:

python - Google App Engine 中的父属性和引用属性有什么区别?

html - 如何在每个表格框周围放置边框?

linux - 从某一行开始对文件进行排序

linux - 安全地打开系统日志文件

Python:如何以颜色打印变量的值

python - 找出组内差异最大的组名

jquery - 在右侧对齐 html 表单(JQuery 移动版)

java - 在 unix 控制台上使用 java 进行 pretty-print

python - groupby 并添加一些行

html - 如何保留编号列表的缩进?