请求模块编码提供不同的编码然后 HTML 编码
Requests module encoding provides different encode then HTML encode
请求模块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
输出:
ISO-8859-1
其中 HTML 中设置的实际编码是 UTF-8
content="text/html; charset=UTF-8"
我的问题是:
- 为什么
requests.encoding
显示的编码与 HTML 页面中描述的编码不同?
我正在尝试使用此方法将编码转换为 UTF-8 objReq.content.decode(encodes).encode("utf-8")
,因为当我使用 ISO-8859-1 解码并使用 UTF-8 编码时它已经在 UTF-8
中值得到改变即)á
对此Ã
的改变
有什么方法可以将所有类型的编码转换为 UTF-8 吗?
请求将首先检查 HTTP header:
中的编码
print obj.headers['content-type']
输出:
text/html
没有正确解析编码猜测的类型,因此它指定了默认的 ISO-8859-1。
在 docs 中查看更多信息。
当您有 text/*
响应并且未在响应 中指定内容类型 header 时,请求将 response.encoding
属性设置为 ISO-8859-1
s.
见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
header:
中查找 charset
参数来对此进行测试
resp = requests.get(....)
encoding = resp.encoding if 'charset' in resp.headers.get('content-type', '').lower() else None
您的 HTML 文档在 <meta>
header 中指定了内容类型,并且正是这个 header 是权威的:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
HTML5还定义了一个<meta charset="..." />
标签,见<meta charset="utf-8"> vs <meta http-equiv="Content-Type">
如果 HTML 页面包含使用不同编解码器的 header,您应该不 将 HTML 页面重新编码为 UTF-8。在这种情况下,您至少必须 更正 header。
使用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 始终是 UTF-8,除非由 <?xml encoding="..." ... ?>
XML 声明指定,这也是文档的一部分。
请求 replies on HTTP Content-Type
响应 header 和 chardet
。对于 text/html
的常见情况,它假定默认值为 ISO-8859-1
。问题是 Requests 对 HTML 元标记一无所知,它可以指定不同的文本编码,例如<meta charset="utf-8">
或 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
.
一个好的解决方案是使用 BeautifulSoup 的“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)
请求模块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
输出:
ISO-8859-1
其中 HTML 中设置的实际编码是 UTF-8
content="text/html; charset=UTF-8"
我的问题是:
- 为什么
requests.encoding
显示的编码与 HTML 页面中描述的编码不同?
我正在尝试使用此方法将编码转换为 UTF-8 objReq.content.decode(encodes).encode("utf-8")
,因为当我使用 ISO-8859-1 解码并使用 UTF-8 编码时它已经在 UTF-8
中值得到改变即)á
对此Ã
有什么方法可以将所有类型的编码转换为 UTF-8 吗?
请求将首先检查 HTTP header:
中的编码print obj.headers['content-type']
输出:
text/html
没有正确解析编码猜测的类型,因此它指定了默认的 ISO-8859-1。
在 docs 中查看更多信息。
当您有 text/*
响应并且未在响应 中指定内容类型 header 时,请求将 response.encoding
属性设置为 ISO-8859-1
s.
见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 containstext
. In this situation, RFC 2616 specifies that the default charset must beISO-8859-1
. Requests follows the specification in this case. If you require a different encoding, you can manually set theResponse.encoding
property, or use the rawResponse.content
.
大胆强调我的。
您可以通过在 Content-Type
header:
charset
参数来对此进行测试
resp = requests.get(....)
encoding = resp.encoding if 'charset' in resp.headers.get('content-type', '').lower() else None
您的 HTML 文档在 <meta>
header 中指定了内容类型,并且正是这个 header 是权威的:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
HTML5还定义了一个<meta charset="..." />
标签,见<meta charset="utf-8"> vs <meta http-equiv="Content-Type">
如果 HTML 页面包含使用不同编解码器的 header,您应该不 将 HTML 页面重新编码为 UTF-8。在这种情况下,您至少必须 更正 header。
使用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 始终是 UTF-8,除非由 <?xml encoding="..." ... ?>
XML 声明指定,这也是文档的一部分。
请求 replies on HTTP Content-Type
响应 header 和 chardet
。对于 text/html
的常见情况,它假定默认值为 ISO-8859-1
。问题是 Requests 对 HTML 元标记一无所知,它可以指定不同的文本编码,例如<meta charset="utf-8">
或 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
.
一个好的解决方案是使用 BeautifulSoup 的“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)