requests get 下来是乱码 咋解决求大佬

2018-02-20 04:01:29 +08:00
 jakeyfly

查����U 是这样的乱码 encoding 显示 None utf-8 也没用 有没有什么办法能变显示正常

5225 次点击
所在节点    问与答
34 条回复
Sylv
2018-02-20 12:43:51 +08:00
@jakeyfly
一般中文网站出现乱码问题,编码基本都是 GBK (GB18030),特别当服务器是 Windows 的时候。
更通用点的方法是用 chardet.detect(r.content) 尝试检测下编码。

我这边返回的是个 js 文件,不是 json 数据,不过这个 js 文件的运行结果貌似是个 json 数据。
jakeyfly
2018-02-20 12:48:26 +08:00
@Sylv JS 只懂一点点 如何得到 JSON 文件呢 我现在用正则 提取有点麻烦 要好几步
axlecho
2018-02-20 12:53:14 +08:00
用 postman 试试 一般都是 gzip 的问题
rieuse
2018-02-20 12:57:07 +08:00
@jakeyfly 成功了吗?没成功的话,加微-信,rieuse 免费给你看看 我也是做爬虫的。
rieuse
2018-02-20 12:59:44 +08:00
html = requests.get(url,headers=headers).content.decode('gbk')
这样就可以了
jakeyfly
2018-02-20 13:00:01 +08:00
@rieuse 大佬 求指导 加微信不
rieuse
2018-02-20 13:01:49 +08:00
不是大佬,我目前爬虫实习生~ 微信就是昵称
flowfire
2018-02-20 13:03:05 +08:00
@ila us
wisej
2018-02-20 13:05:08 +08:00
我来梳理一下吧:

首先 requests 里关于获取编码的几个函数:
1. `get_encodings_from_content`:utils.py 中定义,譬如从 HTML head 的 meta 中获取 charset
2. `get_encoding_from_headers`:从响应头的 Content-Type 来猜测
3. `chardet.detect`: 编码自动检测工具

然后 requests 处理编码方式的流程是这样的:
1. 首先看响应头的 Content-Type 里是否包含 charset,有就设置并返回
2. 若 Content-Type 里没有 charset,但是 MIME 是 text/*,则直接设置编码为 ISO-8859-1 (这一点 requests 是为了遵循 RFC2616/3.7.1 )
3. 当第 1、2 点都不符合时,encoding 为空,才使用 chardet.detect 自动检测

**问题所在**:
第二点导致国内很多网站的编码方式被认为是 ISO-8859-1,在西方国家,没啥大问题。但是在亚洲很多国家,将会出现乱码

具体讨论可以看: https://github.com/requests/requests/issues/1604

PS:
1. 好像 RFC2616 中将默认编码设为 ISO-8859-1 已经被弃用了。然后 requests 上关于这个问题貌似还在讨论...( https://github.com/requests/requests/issues/2086

2. 很多人可能会疑问,为什么 requests 处理编码问题里没有用`get_encodings_from_content`,Lukasa 解释是这样的:
> Our position on this has been that we're not a HTML library, we're a HTTP library, and therefore examining the body of the request is outside our remit.

当然,你可以自行调用嘛:
```
import requests
from requests.utils import get_encodings_from_content

r = requests.get('http://baike.baidu.com/view/115789.htm')
codings = get_encodings_from_content(r.content)
if codings:
r.encoding = codings[0]
```
rieuse
2018-02-20 13:05:59 +08:00
提取方式用 python 去执行 js 代码,js 加入自己的提取逻辑。python 执行 js 代码方式也有很多,可以用 python 开个线程调用 nodejs 来做 或者用 execjs PyExecJS....
jakeyfly
2018-02-20 13:09:43 +08:00
@wisej 感谢大佬
jakeyfly
2018-02-20 13:10:14 +08:00
@rieuse js 没学过 只会 JQUERY 这种东西 原生 JS 感觉 好难
Daniel65536
2018-02-20 22:57:22 +08:00
爬虫编码这块,推荐用这个:

encoding = r.encoding
if encoding in [None, 'ISO-8859-1']:
----encodings = requests.utils.get_encodings_from_content(r.text)
----if encodings:
--------encoding = encodings[0]
----else:
--------encoding = r.apparent_encoding
return r.content.decode(encoding)

chardet.detect 的调用在 requests 里被包裹了一层,用 r.apparent_encoding 可以调用到。
dangyuluo
2018-02-21 01:50:16 +08:00
gzip?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/431288

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX