【问题标题】:How to unescape special characters from BeautifulSoup output?如何从 BeautifulSoup 输出中取消转义特殊字符?
【发布时间】:2011-02-21 08:36:52
【问题描述】:

我遇到了代表华氏度符号和注册符号的特殊字符(如°和®)的问题,

当我打印包含特殊字符的字符串时,它会给出如下输出:

Preheat oven to 350° F
Welcome to Lorem Ipsum Inc® 

有没有办法可以输出确切的字符而不是它们的代码?请告诉我。

【问题讨论】:

  • 你能发布一些我们可以运行的代码来演示这个问题吗?
  • -1 表示不包括 any 代码。
  • 您应该删除您在下面的 cmets 中放入的代码并将其放入您的问题中;您还应该将其标记为代码,以便正确显示(选择块并按 Ctrl+K)。我冒昧地编辑了你的帖子。

标签: python utf-8 character-encoding special-characters beautifulsoup


【解决方案1】:
$ python -c'from BeautifulSoup import BeautifulSoup
> print BeautifulSoup("""<html>Preheat oven to 350&deg; F
> Welcome to Lorem Ipsum Inc&reg;""",
> convertEntities=BeautifulSoup.HTML_ENTITIES).contents[0].string'
Preheat oven to 350° F
Welcome to Lorem Ipsum Inc®

【讨论】:

  • 对不起,请不要误会我的意思,我想要的只是获取注册和摄氏度的符号。我会试试上面提到的那个。
  • 感谢 Sebastian 解决了我的问题,感谢 David 与我的合作。
【解决方案2】:

这是一个脚本,它允许从网页中对 HTML 引用进行转义 - 它假定引用是例如&amp;deg; 格式,后面有分号(例如Preheat oven to 350&amp;deg; F):

from htmlentitydefs import name2codepoint

# Get the whitespace characters
nums_dict = {0: ' ', 1: '\t', 2: '\r', 3: '\n'}
chars_dict = dict((x, y) for y, x in nums_dict.items())
nums_dict2XML = {0: '&#32;', 1: '&#09;', 2: '&#13;', 3: '&#10;'}
chars_dict2XML = dict((nums_dict[i], nums_dict2XML[i]) for i in nums_dict2XML)

s = '1234567890ABCDEF'
hex_dict = {}
for i in s:
    hex_dict[i.lower()] = None
hex_dict[i.upper()] = None
del s

def is_hex(s):
    if not s:
        return False

    for i in s:
        if i not in hex_dict:
            return False
    return True

class Unescape:
    def __init__(self, s, ignore_whitespace=False):
        # Converts HTML character references into a unicode string to allow manipulation
        self.s = s
        self.ignore_whitespace = ignore_whitespace
        self.lst = self.process(ignore_whitespace)

    def process(self, ignore_whitespace):
        def get_char(c):
            if ignore_whitespace:
                return c
            else:
                if c in chars_dict:
                    return chars_dict[c]
                else: return c

        r = []
        lst = self.s.split('&')
        xx = 0
        yy = 0
        for item in lst:
            if xx:
                split = item.split(';')
                if split[0].lower() in name2codepoint:
                    # A character reference, e.g. '&amp;'
                    a = unichr(name2codepoint[split[0].lower()])
                    r.append(get_char(a)) # TOKEN CHECK?
                    r.append(';'.join(split[1:]))

                elif split[0] and split[0][0] == '#' and split[0][1:].isdigit():
                    # A character number e.g. '&#52;'
                    a = unichr(int(split[0][1:]))
                    r.append(get_char(a))
                    r.append(';'.join(split[1:]))

                elif split[0] and split[0][0] == '#' and split[0][1:2].lower() == 'x' and is_hex(split[0][2:]):
                    # A hexadecimal encoded character
                    a = unichr(int(split[0][2:].lower(), 16)) # Hex -> base 16
                    r.append(get_char(a))
                    r.append(';'.join(split[1:]))

                else:
                    r.append('&%s' % ';'.join(split))
            else:
                r.append(item)
            xx += 1
            yy += len(r[-1])
        return r

def get_value(self):
    # Convert back into HTML, preserving
    # whitespace if self.ignore_whitespace is `False`
    r = []
    for i in self.lst:
        if type(i) == int:
            r.append(nums_dict2XML[i])
        else:
            r.append(i)
    return ''.join(r)

def unescape(s):
    # Get the string value from escaped HTML `s`, ignoring
    # explicit whitespace like tabs/spaces etc
    inst = Unescape(s, ignore_whitespace=True)
    return ''.join(inst.lst)

if __name__ == '__main__':
    print unescape('Preheat oven to 350&deg; F')
print unescape('Welcome to Lorem Ipsum Inc&reg;')

编辑:这是一个更简单的解决方案,它仅将字符引用替换为字符而不是 &amp;#xx; 引用:

from htmlentitydefs import name2codepoint

def unescape(s):
    for name in name2codepoint:
        s = s.replace('&%s;' % name, unichr(name2codepoint[name]))
    return s

print unescape('Preheat oven to 350&deg; F')
print unescape('Welcome to Lorem Ipsum Inc&reg;')

【讨论】:

  • recipeDiv= BeautifulSoup.findAll('div', attrs={'id': 'preparation'}) recipeDiv= str(recipeDiv) recipeDiv= BeautifulSoup(recipeDiv) RN= len(recipeDiv('p ')) y=0 while (y
  • 当我打印 recipeDivText 时,我得到如下输出:预热烤箱至 350°F
  • 尝试Unescape(recipeDivText)使用上面的代码,它应该返回正确的结果(如果它实际上返回350&amp;deg;F而不是350&amp;deg F)否则我将不得不修改它
  • 问题是 BeautifulSoup 返回 HTML 内容而不转义 HTML 字符引用 (en.wikipedia.org/wiki/…) - 上面是这样做的
  • 我不能在我的代码中使用那个代码,就像我只是想转义字符串中的 HTML 字符并显示它们的实际符号,因为我不能使用你上面提到的代码,我我假设必须有一些更简单的解决方案。
【解决方案3】:

在美丽的汤4中:

my_text = """Preheat oven to 350&deg; F
Welcome to Lorem Ipsum Inc&reg; """

soup = BeautifulSoup(my_text, 'html.parser')

print(soup)

结果:

Preheat oven to 350° F
Welcome to Lorem Ipsum Inc® 

【讨论】:

  • 太棒了!考虑带括号的print(soup) 与 Python 2 和 3 兼容。
  • 好电话。谢谢。
【解决方案4】:

我想在某个地方,一个程序在没有分号的情况下引用 &deg 和 &reg。 尝试使用“&deg”+“;”和“&reg”+“;”在您的 HTML 文件中,如果它确实是一个 HTML 文件。 并请解释上下文。

【讨论】:

  • 整个场景是这样的:我通过一个 url 从一个 html 页面获取一些数据,一旦我收到数据,我就使用 BeautifulSoup 模块,我在我的变量中接收数据,然后将其转换为字符串格式。 dataText= str(dataText) 当我打印时:打印 dataText 我得到如下输出:预热烤箱至 350&deg F 我需要得到那个确切的符号
猜你喜欢
  • 2017-04-02
  • 1970-01-01
  • 1970-01-01
  • 2017-08-01
  • 1970-01-01
  • 2016-02-27
  • 2012-03-14
  • 2013-06-09
  • 1970-01-01
相关资源
最近更新 更多