请求模块编码提供与HTML编码不同的编码

2024-10-02 20:32:49 发布

您现在位置:Python中文网/ 问答频道 /正文

请求模块encoding提供了与HTML页面中实际设置的编码不同的编码

代码:

import requests
URL = "http://www.reynamining.com/nuevositio/contacto.html"
obj = requests.get(URL, timeout=60, verify=False, allow_redirects=True)
print obj.encoding

输出:

^{pr2}$

其中,HTML中的实际编码集是UTF-8content="text/html; charset=UTF-8"

我的问题是:

  1. 为什么requests.encoding显示的编码与HTML页面中描述的编码不同?。在

我正试图使用这个方法objReq.content.decode(encodes).encode("utf-8")将编码转换为UTF-8,因为它已经在UTF-8中,当我用ISO-8859-1解码并用UTF-8编码时,值发生了变化,即á更改为Ã

有没有办法把所有类型的编码转换成UTF-8?在


Tags: 模块代码importobjhttpurl编码html
3条回答

当您有一个text/*响应且响应头中未指定任何内容类型时,Requests将response.encoding属性设置为ISO-8859-1。在

参见Encoding section of the Advanced documentation

The only time Requests will not do this is if no explicit charset is present in the HTTP headers and the Content-Type header contains text. In this situation, RFC 2616 specifies that the default charset must be ISO-8859-1. Requests follows the specification in this case. If you require a different encoding, you can manually set the Response.encoding property, or use the raw Response.content.

大胆强调我的。在

您可以通过在Content-Type头中查找charset参数来进行测试:

resp = requests.get(....)
encoding = resp.encoding if 'charset' in resp.headers.get('content-type', '').lower() else None

您的HTML文档在<meta>头中指定了内容类型,并且此标题是权威的:

^{pr2}$

HTML5还定义了一个<meta charset="..." />标记,请参见<meta charset="utf-8"> vs <meta http-equiv="Content-Type">

如果HTML页面包含这样一个具有不同编解码器的报头,则应该将其重新编码为UTF-8。在这种情况下,您至少必须纠正标题。在

使用BeautifulSoup:

# pass in explicit encoding if set as a header
encoding = resp.encoding if 'charset' in resp.headers.get('content-type', '').lower() else None
content = resp.content
soup = BeautifulSoup(content, from_encoding=encoding)
if soup.original_encoding != 'utf-8':
    meta = soup.select_one('meta[charset], meta[http-equiv="Content-Type"]')
    if meta:
        # replace the meta charset info before re-encoding
        if 'charset' in meta.attrs:
            meta['charset'] = 'utf-8'
        else:
            meta['content'] = 'text/html; charset=utf-8'
    # re-encode to UTF-8
    content = soup.prettify()  # encodes to UTF-8 by default

类似地,其他文档标准也可能指定特定的编码;例如,除非由<?xml encoding="..." ... ?>XML声明指定,否则XML总是UTF-8,这也是文档的一部分。在

请求将首先检查HTTP头中的编码:

print obj.headers['content-type']

输出:

^{pr2}$

无法正确解析编码猜测的类型,因此它指定了默认的ISO-8859-1。在

更多信息请参见docs。在

请求replies onHTTP Content-Type响应头和chardet。对于text/html的常见情况,它假定默认值为ISO‌-8859-1。问题是请求对HTML元标记一无所知,它可以指定不同的文本编码,例如<meta charset="utf-8">或{}。在

一个好的解决方案是使用beauthoulsoup的“Unicode, Dammit”功能,如下所示:

from bs4 import UnicodeDammit
import requests


url = 'http://www.reynamining.com/nuevositio/contacto.html'
r = requests.get(url)

dammit = UnicodeDammit(r.content)
r.encoding = dammit.original_encoding

print(r.text)

相关问题 更多 >