【问题标题】:Python3 html and lxml parser encoding problemPython3 html和lxml解析器编码问题
【发布时间】:2018-09-01 11:15:06
【问题描述】:

当使用BeautifulSoupPyQuery 解析某些HTML 时,它们将使用lxmlhtml5lib 之类的解析器。假设我有一个包含以下内容的文件

<span>  é    and    ’  </span>

在我的环境中,它们似乎编码不正确,使用 PyQuery:

>>> doc = pq(filename=PATH, parser="xml")
>>> doc.text()
'é and â\u20ac\u2122'
>>> doc = pq(filename=PATH, parser="html")
>>> doc.text()
'Ã\x83© and ââ\x82¬â\x84¢'
>>> doc = pq(filename=PATH, parser="soup")
>>> doc.text()
'é and â\u20ac\u2122'
>>> doc = pq(filename=PATH, parser="html5")
>>> doc.text()
'é and â\u20ac\u2122'

除了编码似乎不正确这一事实之外,主要问题之一是doc.text() 返回str 的实例而不是bytes,根据我昨天问过的that question,这不是正常的事情。

另外,将参数encoding='utf-8' 传递给PyQuery 似乎没用,我试过'latin1' 没有任何改变。我还尝试添加一些元数据,因为我读到 lxml 读取它们以找出要使用的编码但它不会改变任何东西:

<!DOCTYPE html>
<html lang="fr" dir="ltr">
<head>
<meta http-equiv="content-type" content="text/html;charset=latin1"/>
<span>  é    and    ’  </span>
</head>
</html>  

如果我直接使用lxml 似乎有点不同

>>> from lxml import etree
>>> tree = etree.parse(PATH)
>>> tree.docinfo.encoding
'UTF-8'

>>> result = etree.tostring(tree.getroot(), pretty_print=False)
>>> result
b'<span>  &#233;    and    &#8217;  </span>'

>>> import html
>>> html.unescape(result.decode('utf-8'))
'<span>  é    and    \u2019  </span>\n'

Erf,这让我有点抓狂,不胜感激您的帮助

【问题讨论】:

  • 我认为问题出在 filename=PATH 中,因为当我从 pyquery 运行时 import PyQuery as pq \n html = ' é and ' ' \n doc = pq (html, parser='html') \n print(doc.text()),它返回"é and '"

标签: html python-3.x utf-8 beautifulsoup lxml


【解决方案1】:

我想我明白了。看来,即使 BeautifulSoup 或 PyQuery 能够做到这一点,直接打开包含一些特殊 UTF-8 字符的文件也是一个坏主意。特别是,最让我困惑的是我的 Windows 终端似乎没有正确处理的 ''' 符号。因此,解决方案是在解析文件之前对其进行预处理:

def pre_process_html_content(html_content, encoding=None):
    """Pre process bytes coming from file or request."""
    if not isinstance(html_content, bytes):
        raise TypeError("html_content must a bytes not a " + str(type(html_content)))

    html_content = html_content.decode(encoding)


    # Handle weird symbols here
    html_content = html_content.replace('\u2019', "'")

    return html_content


def sanitize_html_file(path, encoding=None):
    with open(path, 'rb') as f:
        content = f.read()
    encoding = encoding or 'utf-8'

    return pre_process_html_content(content, encoding)


def open_pq(path, parser=None, encoding=None):
    """Macro for open HTML file with PyQuery."""
    content = sanitize_html_file(path, encoding)
    parser = parser or 'xml'

    return pq(content, parser=parser)


doc = open_pq(PATH)

【讨论】:

    猜你喜欢
    • 2013-02-24
    • 2015-06-23
    • 2014-05-17
    • 2023-04-09
    • 2013-03-27
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    • 2017-06-19
    相关资源
    最近更新 更多